我已经使用async.waterfall展平了嵌套函数,如下所示。
function convertPortfolio(trademarks, fn){
async.waterfall([function(callback){
groupByCountry(trademarks, callback)
},
function(TMsGroupedByCountry, callback){
addEUTrademarks(TMsGroupedByCountry['EU'], TMsGroupedByCountry, callback)
},
function(revisedGroupByCountry, callback){
groupTrademarksByStatus(revisedGroupByCountry, callback)
}], function(err, splitByStatus){
fn(null, splitByStatus);
})
}
嵌套替代
function convertPortfolio(trademarks, fn){
groupByCountry(trademarks, function(err, TMsGroupedByCountry){
addEUTrademarks(TMsGroupedByCountry['EU'], TMsGroupedByCountry, function(err, revisedGroupByCountry){
groupTrademarksByStatus(revisedGroupByCountry, function(err, splitByStatus){
fn(null, splitByStatus)
});
});
});
}
随后,当我将此函数作为另一个函数的一部分调用一次时,它可以完美运行。但是,当我尝试使用与数组上的forEach调用不同的值多次调用该函数时,当嵌套版本可以正常工作时,该函数将无法工作。我无所适从地解释为什么会这样,老实说,我不确定从哪里开始。我的理解是,forEach调用应仅意味着对每个单独的值进行相应的处理并关闭,因此这不是问题。
异步功能正常工作并在此实例中返回值
exports.convertPortfolioAndAddToGeoJSON = function(geojson, trademarks, fn){
convertPortfolio(trademarks, function(err, revisedTMs){
addToGeoJson(geojson, revisedTMs, function(err, gj){
fn(null, gj)
});
});
}
但是在这种情况下,不会填充最终目标对象:
exports.convertYearPortfolioAndAddToGeoJSON = function(geojson, trademarks, fn){
var target = {};
Object.keys(trademarks).forEach(function(year){
convertPortfolio(trademarks[year], function(err, revisedTMs){
addToGeoJson(geojson, revisedTMs, function(err, revisedGeoJSON){
target[year] = revisedGeoJSON;
});
});
});
fn(null, target);
}
在某些时候使用console.log可以表明,在嵌套示例中,返回值是在记录目标对象之前记录的,而在async.waterfall示例中,目标对象是在返回数据可用之前记录的(因此,假设记录目标会导致一个空对象也就不足为奇了。
我认为在每种情况下都存在回调,这意味着仅在完成所有先前处理后才记录目标,但是尽管嵌套替代似乎是这种情况,但异步情况并非如此至少在多次调用时才版本。
任何指导将不胜感激。
更新出于兴趣,这里是使用async.forEach修改的代码:
exports.convertYearPortfolioAndAddToGeoJSON = function(geojson, trademarks, fn){
var target = {};
async.forEach(Object.keys(trademarks), function(year, callback){
async.waterfall([
async.apply(convertPortfolio, trademarks[year]),
function(revisedTMs, callback){
addToGeoJson(geojson, revisedTMs, callback)
}],
function(err, revisedGeoJSON){
target[year] = revisedGeoJSON;
callback()
})
}, function(err){
fn(null, target);
});
}
Object.keys(trademarks).forEach
是同步的,无法正确跟踪闭包/作用域。您需要在async.forEach(Object.keys(trademarks), function(year, callback)....
那里使用,并相应地调整异步控制流。
当您使用带有微小包装函数的模式时,也仅供参考:
function convertPortfolio(trademarks, fn){
async.waterfall([function(callback){
groupByCountry(trademarks, callback)
},
您可以使用async.apply
该样板:
function convertPortfolio(trademarks, fn){
async.waterfall([async.apply(groupByCountry, trademarks),
...
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句