好的,从阅读这篇文章回来,给出一个更完整的答案。这种策略适用于相互依赖但并不总是相同的异步任务。如果它们是一个固定结构,您可以(从示例中)执行以下操作:
return task1.then(result1 =>
task2.then(result2 =>
task3.then(result3 =>
[ result1, result2, result3 ]
)
)
).then(arrayOfResults => {
// Do something with all results
});
return dbOrm.task1.create()
.then(newRecord =>
// task 2 requires the id from the new record to operate
dbOrm.task2.create({task1_id: newRecord.id})
.then(result2 =>
// some other async that relies on result2
task3(result2).then(result3 =>
[ result1, result2, result3 ]
)
)
).then(arrayOfResults => {
// Do something with all results
});
这是一组固定的依赖项,它们相互依赖以进行操作,您需要所有依赖项的结果才能继续。
您链接的示例是针对这种串行执行的,但是在具有非固定依赖关系的情况下。Reduce用于同步构建异步操作链,然后这些异步操作可以自行解析,并且由于Reduce函数返回已解析的承诺,因此您可以将另一个函数从其末端链接起来,以处理完成的链。
Reduce不仅仅是一个forEach循环,即使它们都使用迭代来移动数组。Reduce还将上一次迭代的返回结果传递给下一次迭代。您正在将您的任务组“减少”为一个已完成的任务;forEach不改变它所操作的数组(而Map,另一个迭代数组函数,从旧数组返回一个修改过的新数组)。
因此,使用示例代码:
const tasks = getTaskArray();
return tasks.reduce((promiseChain, currentTask) => {
return promiseChain.then(chainResults =>
currentTask.then(currentResult =>
[ ...chainResults, currentResult ]
)
);
}, Promise.resolve([])).then(arrayOfResults => {
// Do something with all results
});
// 1
Promise.resolve([])
.then(chainResults => task1().then(task1Result => ([ ...chainResults, task1Result])
// 2
Promise.resolve([])
.then(chainResults => task1().then(task1Result => ([ ...chainResults, task1Result])
.then(chainResults => task2().then(task2Result => ([ ...chainResults, task2Result])
// the then after the reduce
Promise.resolve([])
.then(chainResults => task1().then(task1Result => ([ ...chainResults, task1Result])
.then(chainResults => task2().then(task2Result => ([ ...chainResults, task2Result])
.then(arrayOfResults => //do Something)
.catch(//because you should handle errors)