0

根据我的阅读,javascript 中的嵌套函数会导致额外的声明/破坏,这可以通过使用“静态函数”甚至单例实现来避免。在函数或对象的两个实例也是独立副本的情况下,“新”也会做同样的事情。

这是真的?如果是这样,我该怎么做才能拥有与嵌套函数和“新”相同的功能。这适用于服务器位于 nodejs / javascript 中的游戏。我已经达到了大约 8 个级别的嵌套函数并且开始担心。

例子:

DB.cityUpdateUpkeep = function( cuid )
{
/**  @type {Array} */
var buildings = null;

DB.cityGet( cuid, function( error, city )
{
    if( error )
    {
        console.log( "Couldn't get city" );
    }
    else
    {
        DB.iBuildings.find( {cuid:cuid}, function( error, cursor )
        {
            if( error )
            {
                console.log( "-error:" );
                console.log( error );
            }
            else
            {
                cursor.toArray( function( error, response )
                {
                    if( error )
                    {
                        console.log( "-error:" );
                        console.log( error );
                    }
                    else
                    {
                        console.log( "-the response:" );
                        console.log( response );
                        buildings = response;

                        var income  = city.resources.income;
                        var storage = city.resources.storage;
                        var stored  = city.resources.stored;

                        for( var buildingID in buildings )
                        {
                            var building = buildings[ buildingID ];
                            var blueprint = DB.bBuildings[ building.buid ];

                            if( blueprint.resources.income )
                            {
                                income = Utils.sumObjects( income, blueprint.resources.income );
                            }

                            if( blueprint.resources.storage )
                            {
                                storage = Utils.sumObjects( storage, blueprint.resources.storage );
                            }

                            if( blueprint.resources.stored )
                            {
                                stored = Utils.sumObjects( stored, blueprint.resources.stored );
                            }
                        }

                        console.log( "cuid: " + city._id + " income: " + income + " storage " + storage + " stored " + stored );
                    }
                });
            }
        });
    }
});
};
4

3 回答 3

1

查看Q以了解扁平化回调的方法(代码会更好一些)。对于您的具体示例,我更愿意使用多种方法进行重构:

  1. 出错时尽早返回方法(使您不必嵌套其他方法)
  2. 当它们不依赖时并发执行异步调用(注意 DB.cityGet 和 DB.iBuildings.find - 使您的代码也运行得更快)
  3. 在嵌套之外创建函数和引用(例如 checkComplete)

我的重构如下:

  DB.cityUpdateUpkeep = function( cuid ){
    /**  @type {Array} */
    var buildings = null;
    var city = null;
    var checkComplete = function(){
        if (!city || !builings){
            return;
        }   
        var income  = city.resources.income;
        var storage = city.resources.storage;
        var stored  = city.resources.stored;

        for( var buildingID in buildings ){
            var building = buildings[ buildingID ];
            var blueprint = DB.bBuildings[ building.buid ];

            if( blueprint.resources.income ){
                income = Utils.sumObjects( income, blueprint.resources.income );
            }   

            if( blueprint.resources.storage ){
                storage = Utils.sumObjects( storage, blueprint.resources.storage );
            }   

            if( blueprint.resources.stored ){
                stored = Utils.sumObjects( stored, blueprint.resources.stored );
            }   
        }   

        console.log( "cuid: " + city._id + " income: " + income + " storage " + storage + " stored " + stored );

    }   
    DB.cityGet(cuid, function(err, response){
        if (err){
            console.log("Couldn't get city");
            return;
        }   
        city = response;
        checkComplete();
    }); 
    DB.iBuildings.find({cuid:cuid}, function(err, cursor){
        if (err){
            console.log(err);
            return;
        }   
        cursor.toArray(function(err, response){
            if (err){
                console.log(err)
                return;
            }   
            buildings = response;
            checkComplete(); 
        }); 
    }); 
});
于 2013-05-15T08:05:36.413 回答
0

我建议你选择一个控制流库(异步是最流行的)而不是一堆回调,你可以选择waterfall

async.parallel([
    function(callback){
        setTimeout(function(){
            callback(null, 'one');
        }, 200);
    },
    function(callback){
        setTimeout(function(){
            callback(null, 'two');
        }, 100);
    }
],
// optional callback
function(err, results){
    // the results array will equal ['one','two'] even though
    // the second function had a shorter timeout.
});

(代码是从 async 的主网站借来的)。所以如果你想在这些嵌套函数之间共享一个变量,你可以定义它在DB.cityUpdateUpkeep哪个顶层,其他嵌套函数可以使用它。但是请注意,如果您随时修改变量,稍后运行的函数将受到影响。

而且,这些嵌套函数有多糟糕?没什么,这是 nodejs 的本质(异步编程模型),你必须忍受它。不过,您将不得不重新安排代码以便于维护

于 2013-05-15T06:38:54.633 回答
0

一种解决方案是存储函数而不是匿名回调。重用它们也更容易。

DB.cityUpdateUpkeep = function (cuid) {
    var findHandler = function () { ... };

    DB.cityGet(cuid, function (error, city) {
        ...
        DB.iBuildings.find({cuid:cuid}, findHandler);
        ...
    });
};
于 2013-05-14T13:19:26.960 回答