Promise.all() 原理解析及使用指南

Promise 对象是 ECMAScript 6 中新增的对象,主要将 JavaScript 中的异步处理对象和处理规则进行了规范化。前面介绍了《Promise.any() 原理解析及使用指南》,本文来介绍另一个方法 Promise.all(promises) ,能够一次并行处理多个 promise,并且只返回一个 promise 实例, 那个输入的所有 promise 的 resolve 回调的结果是一个数组。
下面来看看 Promise.all() 是如何工作的。
1.工作原理
Promise.all() 是一个内置的辅助函数,接受一组 promise(或者一个可迭代的对象),并返回一个promise :
可以使用 then 方法提取第一个 promise 的值:
也可以使用 async/await 语法:
Promise.all() 返回的 promise 被解析或拒绝的方式。
如果 allPromise 都被成功解析,那么 allPromise 将使用一个包含各个 promise 已执行完成后的值的数组作为结果。数组中 promise 的顺序是很重要的——将按照这个顺序得到已实现的值。
但是如果至少有一个 promise 被 rejected ,那么 allPromise 会以同样的原因立即 rejected (不等待其他 promise 的执行)。
如果所有的 promise 被 rejected ,等待所有的promise 执行完成,但只会返回最先被rejected 的promise 的 reject 原因。
2. 使用指南
现在来看一下 Promise.all()的实际使用情况, 在这之前,先来定义 2 个简单的函数。
函数
resolveTimeout(value, delay)将返回一个在经过delay时间后有resolve的promise。
函数
rejectTimeout(reason, delay)将返回一个在经过delay时间后有reject的promise。
接下来使用上面定义的 2 个辅助函数来试试 Promise.all() 。
2.1 完成所有 promises
下面定义了一个 promise 数组 allPromise ,所有的 promise 都能够成功的 resolve 值,如下:
从上面执行的结果来看 Promise.all() 返回的 promise 的 resolve 数组是按照执行前 allPromise 的顺序组成其结果。
promise数组的顺序直接影响结果的顺序,和promise执行完成的先后无关。
2.2 一个 promise 被 rejected
将上面数组 allPromise 的第一个 promise 出现异常被 rejected ,如下代码:
然而,在经过 5秒 之后,第一个 promise 由于异常被 rejected ,使得 allPromise 也被 rejected ,并返回跟第一个 promise 一样的错误信息:Error: fruits is empty ,即使在 1秒 后就完成的第二个 promise 的值也不被采纳。
接下来将数组 allPromise 的所有 promise 都抛出异常被 rejected ,通过定时器将 rejected 的顺序做个调整,如下:
经过 5秒 之后完成执行,而结果显示为 Error: vegetables is empty ,不难看出 allPromise 被 rejected 的原因是最先 rejected 的promise 。
Promise.all()的这种行为被称为快速失败,如果promise数组中至少有一个promise被rejected,那么返回的promise也被拒绝。如果promise数组中所有的都被rejected,那么返回的promise被拒绝的原因是先rejected的那一个。
总结
Promise.all() 是并行执行异步操作并获取所有 resolve 值的最佳方法,非常适合需要同时获取异步操作结果来进行下一步运算的场合。
版权声明: 本文为 InfoQ 作者【devpoint】的原创文章。
原文链接:【http://xie.infoq.cn/article/4abd32af04509db35196a5d35】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。











评论