根据我的阅读,javascript中的嵌套函数会导致额外的声明/破坏,这可以通过使用“静态函数”甚至单例实现来避免。同样“new”也可以做同样的事情,其中函数或对象的两个实例也是独立的副本。
这是真的吗?如果是这样,我该怎么做才能拥有与嵌套函数和“new”相同的功能。这适用于服务器位于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 );
}
});
}
});
}
});
};
答案 0 :(得分:1)
看一下Q有关扁平回调的方法(代码会更好)。对于您的具体示例,我更倾向于使用多种方法进行重构:
我的重构如下:
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();
});
});
});
答案 1 :(得分:0)
一种解决方案是存储函数而不是匿名回调。它也更容易重复使用。
DB.cityUpdateUpkeep = function (cuid) {
var findHandler = function () { ... };
DB.cityGet(cuid, function (error, city) {
...
DB.iBuildings.find({cuid:cuid}, findHandler);
...
});
};
答案 2 :(得分:0)
我建议您选择一个控制流库(async是最受欢迎的一个)而不是一堆回调,你可以选择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本质(异步编程模型),你必须忍受它。您必须重新安排代码以便于维护,但