我经常遇到 async.series 任务需要多个先前任务的结果的情况。 async.waterfall 是不够的,因为它只提供上一个任务的结果。 async,auto 过于冗长,并提供了额外的、不需要的依赖声明。
一个新功能(或 async.series 的改进)会派上用场。 每个任务都会收到一个结果对象,其中包含所有先前任务的结果
可能的名称:accumulate、seriesAccumulate
例子:
async.accumulate({
one: function(callback){
setTimeout(function(){
callback(null, 1);
}, 200);
},
two: function(callback, results){
// results: {one: 1}
setTimeout(function(){
callback(null, 2);
}, 100);
},
three: function(callback, results){
// results: {one: 1, two: 2}
setTimeout(function(){
callback(null, results.one + results.two);
}, 100);
}
},
function(err, results) {
// results is now equal to: {one: 1, two: 2, three: 3}
});
你检查过async.auto
吗? 它的作用与您所描述的非常相似。
正如我提到的,在一个简单的系列场景中 async.auto 过于冗长,用户必须声明每个步骤都依赖于前一个步骤,从而导致那些丑陋的数组和重复的步骤名称
async.auto({
one: function(callback){
setTimeout(function(){
callback(null, 1);
}, 200);
},
two: ["one", function(callback, results){
setTimeout(function(){
callback(null, 2);
}, 100);
}],
three: ["two", function(callback, results){
setTimeout(function(){
callback(null, results.one + results.two);
}, 100);
}
]
},
function(err, results) {
// results is now equal to: {one: 1, two: 2, three: 3}
});
我们将在下一个主要版本中对 auto 进行一些增强——始终将回调放在最后,并添加autoInject
(#608),它从参数名称推断依赖关系。
我不喜欢这个提议,因为它依赖于对象键的顺序——这在 JS 环境中是不能保证的(并且只有在 Node 中才能保证小对象)。 使用数组是可能的,但它与async.waterfall
太相似auto
和waterfall
,特别是如果我们添加autoInject
。
一种实现你想要的方法:
function seriesAccumulate(tasks, done) {
async.reduce(tasks, [], function (results, task, next) {
task(results, function (err, result) {
results.push(result);
next(err, result);
});
}, done);
}
我建议不要尝试使用对象进行系列迭代。
关闭这个。 我认为我们不需要另一种介于series
和waterfall
的方法。