【发布时间】:2014-05-06 03:29:51
【问题描述】:
我使用 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);
});
}
【问题讨论】:
标签: javascript node.js async.js