Javascript 中的Promise.all()
方法是一个函数,它接受许多承诺,然后只有在它们全部确定后才做某事。从您输入的所有承诺中,它会创建一个新的承诺,然后等待每个承诺完成,然后再继续。这最终意味着您可以等待多项事情完成,然后再开火其他事情。
此方法对于 UI 开发特别有用 – 例如,如果您希望在屏幕上显示一个加载符号直到多个承诺结束,则Promise.all()
提供了一种简单的方法来执行此操作。让我们看看它是如何工作的。
Javascript Promise.all() 方法#
Promise.all()
接受可迭代的承诺。这意味着它可以接受任何可以迭代的东西——比如数组。您不能在其中放置对象或单一承诺。让我们看一个使用超时的简单示例:
let myPromise = () => { return new Promise((resolve) => { setTimeout(function() { resolve('firstPromise') }, 500) }) } let mySecondPromise = () => { return new Promise((resolve) => { setTimeout(function() { resolve('secondPromise') }, 800) }) }
这里我们有两个超时,其中最长的需要 800 毫秒。我们希望控制台在两者都完成后记录每个值。最简单的方法是使用Promise.all()
:
Promise.all([ myPromise(), mySecondPromise() ]).then((data) => { console.log(data) // Console logs [ 'firstPromise', 'secondPromise' ] })
如您所见,Promise.all()
是 thennable,返回的数据是每个 promise 的结果数组。因此,由于我们传入了myPromise, mySecondPromise
,所以我们以相同的顺序获取数组中每个的数据。
虽然这样使用可能很诱人await
:
let myPromiseFinish = await myPromise() let mySecondPromiseFinish = await mySecondPromise() console.log([ myPromiseFinish, mySecondPromiseFinish ])
这实际上效率较低。await
导致两个函数一个接一个地运行。这意味着通过使用await
,完成两个承诺所花费的总时间将为1300ms
。Promise.all()
允许您同时运行两个承诺,这意味着整个操作可以进行800ms
– 这对于了解您是否正在寻找优化代码非常有用。
使用 Promise.all() 扩展承诺结果
由于Promise.all()
将返回一个结果数组,并创建一个新的承诺,我们可以使用await
with Promise.all()
,并像这样捕获它的输出:
let [ myPromiseResult, mySecondPromiseResult ] = await Promise.all([ myPromise(), mySecondPromise() ])
现在,一旦完成处理,我们承诺的两个结果都可用Promise.all()
。很酷,对吧?
承诺拒绝
请务必注意,如果您的 promise 触发reject
而不是resolve
,Promise.all()
也会立即触发reject
。如果您不熟悉 promise 拒绝,那么当您使用reject
函数而不是resolve
函数时。下面,承诺将始终拒绝并抛出错误Uncaught firstPromise
:
let myPromise = () => { return new Promise((resolve, reject) => { setTimeout(function() { reject('firstPromise') }, 500) }) }
所以,如果你的Promise.all()
集合中的一个承诺被拒绝,一定要预料到它Promise.all()
也会被拒绝。
结论#
Promise.all()
是一种非常有用的方法来简化你的代码,并且在某些情况下还可以加快它的速度 – 通过让你同时做承诺。如果您是 Javascript 的新手,了解 promises 和异步函数在 Javascript 中的工作方式是很棘手的,因此我写了另一篇关于它的指南 –您可以在此处了解有关 promises 的更多信息。