如何理解Array的reduce方法中引入Promise.resolve

How to understand the introduction of Promise.resolve in the reduce method of Array

const tasks = [f1, f2, f3];
        tasks.reduce(async (promise, task) => {
            await promise;
            await task();
        }, Promise.resolve)

这种使用 .reduce() 的设计模式是序列化一些 promise-returning 操作。因此,逻辑是你等待上一个承诺,然后当它完成时你执行你的下一个任务和 return 一个承诺作为下一个循环的值通过循环可以重复该过程。

要使第一次迭代在没有第一次迭代的特殊代码的情况下工作,您需要一个最初可以等待的承诺。因此,您将使用 Promise.resolve() 创建的已解决的承诺传递给 "prime the pump" 并为其提供初始承诺。

如果你打开 .reduce() 循环,在你的例子中,你基本上会得到这样的结果:

Promise.resolve().then(f1).then(f2).then(f3)

Promise.resolve() 开始链避免在循环的第一次迭代中使用特殊外壳。

可以写成:

f1().then(f2).then(f3)

但是,第一个任务的特殊情况确实使使用 .reduce() 之类的东西变得复杂,当你在循环的每次迭代中做同样的事情时,它是最简单的。因此,以 Promise.resolve() 开始允许第一次迭代做与所有其他迭代完全相同的事情。

至于你的两个要点:

The role of Promise.resolve()

.reduce() 一个要等待的第一次迭代的初始承诺。

The role of await promise

在调用下一个任务之前等待循环的上一次迭代的任务完成。


注意:要完全理解这段代码,您必须完全理解 .reduce() 的工作原理。你传递给它两个参数,你的回调函数和一个初始值。该初始值作为回调的第一个参数(您命名为 promise)传递给回调的第一次迭代。

然后,无论您从该回调中 return 获得什么值,都将作为值传递给回调的下一次迭代。由于您使用的是 async 回调,它总是 return 是一个承诺,您的回调将始终 return 一个承诺,它将传递给回调的下一次迭代。而且,因为你的回调做的第一件事是 await promise,你最终得到 "chaining" 承诺,它序列化你的任务的执行。