Promise.all
接收一个 promise对象的数组作为参数,当这个数组里的所有promise对象全部变为resolve或reject状态的时候,它才会去调用 .then
方法。
前面我们看到的批量获得若干XHR的请求结果的例子,使用 Promise.all
的话代码会非常简单。
之前例子中的 getURL
返回了一个promise对象,它封装了XHR通信的实现。
向 Promise.all
传递一个由封装了XHR通信的promise对象数组的话,则只有在全部的XHR通信完成之后(变为FulFilled或Rejected状态)之后,才会调用 .then
方法。
link:embed/embed-promise-all-xhr.js[role=include]
// 运行示例
main().then(function (value) {
console.log(value);
}).catch(function(error){
console.log(error);
});
这个例子的执行方法和 前面的例子 一样。
不过Promise.all
在以下几点和之前的例子有所不同。
-
main中的处理流程显得非常清晰
-
Promise.all 接收 promise对象组成的数组作为参数
Promise.all([request.comment(), request.people()]);
在上面的代码中,request.comment()
和 request.people()
会同时开始执行,而且每个promise的结果(resolve或reject时传递的参数值),和传递给 Promise.all
的promise数组的顺序是一致的。
也就是说,这时候 .then
得到的promise数组的执行结果的顺序是固定的,即 [comment, people]。
main().then(function (results) {
console.log(results); // 按照[comment, people]的顺序
});
如果像下面那样使用一个计时器来计算一下程序执行时间的话,那么就可以非常清楚的知道传递给 Promise.all
的promise数组是同时开始执行的。
link:embed/embed-promise-all-timer.js[role=include]
timerPromisefy
会每隔一定时间(通过参数指定)之后,返回一个promise对象,状态为FulFilled,其状态值为传给 timerPromisefy
的参数。
而传给 Promise.all
的则是由上述promise组成的数组。
var promises = [
timerPromisefy(1),
timerPromisefy(32),
timerPromisefy(64),
timerPromisefy(128)
];
这时候,每隔1, 32, 64, 128 ms都会有一个promise发生 resolve
行为。
也就是说,这个promise对象数组中所有promise都变为resolve状态的话,至少需要128ms。实际我们计算一下Promise.all
的执行时间的话,它确实是消耗了128ms的时间。
从上述结果可以看出,传递给 Promise.all
的promise并不是一个个的顺序执行的,而是同时开始、并行执行的。
Note
|
如果这些promise全部串行处理的话,那么需要 等待1ms → 等待32ms → 等待64ms → 等待128ms ,全部执行完毕需要225ms的时间。 要想了解更多关于如何使用Promise进行串行处理的内容,可以参考第4章的Promise中的串行处理中的介绍。 |