[`Promise.all`](http://liubin.github.io/promises-book/#Promise.all)?接收一個 promise對象的數組作為參數,當這個數組里的所有promise對象全部變為resolve或reject狀態的時候,它才會去調用?`.then`?方法。
前面我們看到的批量獲得若干XHR的請求結果的例子,使用?[`Promise.all`](http://liubin.github.io/promises-book/#Promise.all)?的話代碼會非常簡單。
之前例子中的?`getURL`?返回了一個promise對象,它封裝了XHR通信的實現。 向?`Promise.all`?傳遞一個由封裝了XHR通信的promise對象數組的話,則只有在全部的XHR通信完成之后(變為FulFilled或Rejected狀態)之后,才會調用?`.then`?方法。
promise-all-xhr.js
~~~
function getURL(URL) {
return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest();
req.open('GET', URL, true);
req.onload = function () {
if (req.status === 200) {
resolve(req.responseText);
} else {
reject(new Error(req.statusText));
}
};
req.onerror = function () {
reject(new Error(req.statusText));
};
req.send();
});
}
var request = {
comment: function getComment() {
return getURL('http://azu.github.io/promises-book/json/comment.json').then(JSON.parse);
},
people: function getPeople() {
return getURL('http://azu.github.io/promises-book/json/people.json').then(JSON.parse);
}
};
function main() {
return Promise.all([request.comment(), request.people()]);
}
// 運行示例
main().then(function (value) {
console.log(value);
}).catch(function(error){
console.log(error);
});
~~~
這個例子的執行方法和?[前面的例子](http://liubin.github.io/promises-book/#xhr-promise.js)?一樣。 不過[`Promise.all`](http://liubin.github.io/promises-book/#Promise.all)?在以下幾點和之前的例子有所不同。
* main中的處理流程顯得非常清晰
* Promise.all 接收 promise對象組成的數組作為參數
~~~
Promise.all([request.comment(), request.people()]);
~~~
在上面的代碼中,`request.comment()`?和?`request.people()`?會同時開始執行,而且每個promise的結果(resolve或reject時傳遞的參數值),和傳遞給?[`Promise.all`](http://liubin.github.io/promises-book/#Promise.all)?的promise數組的順序是一致的。
也就是說,這時候?`.then`?得到的promise數組的執行結果的順序是固定的,即 [comment, people]。
~~~
main().then(function (results) {
console.log(results); // 按照[comment, people]的順序
});
~~~
如果像下面那樣使用一個計時器來計算一下程序執行時間的話,那么就可以非常清楚的知道傳遞給?[`Promise.all`](http://liubin.github.io/promises-book/#Promise.all)?的promise數組是同時開始執行的。
promise-all-timer.js
~~~
// `delay`毫秒后執行resolve
function timerPromisefy(delay) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(delay);
}, delay);
});
}
var startDate = Date.now();
// 所有promise變為resolve后程序退出
Promise.all([
timerPromisefy(1),
timerPromisefy(32),
timerPromisefy(64),
timerPromisefy(128)
]).then(function (values) {
console.log(Date.now() - startDate + 'ms');
// 約128ms
console.log(values); // [1,32,64,128]
});
~~~
`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`](http://liubin.github.io/promises-book/#Promise.all)?的執行時間的話,它確實是消耗了128ms的時間。
從上述結果可以看出,傳遞給?[`Promise.all`](http://liubin.github.io/promises-book/#Promise.all)?的promise并不是一個個的順序執行的,而是同時開始、并行執行的。
> 如果這些promise全部串行處理的話,那么需要 等待1ms → 等待32ms → 等待64ms → 等待128ms ,全部執行完畢需要225ms的時間。
> 要想了解更多關于如何使用Promise進行串行處理的內容,可以參考第4章的[Promise中的串行處理](http://liubin.github.io/promises-book/#promise-sequence)中的介紹。
- 前言
- 第一章 - 什么是Promise
- 1.1. 什么是Promise
- 1.2. Promise簡介
- 1.3. 編寫Promise代碼
- 第二章 - 實戰Promise
- 2.1. Promise.resolve
- 2.2. Promise.reject
- 2.3. 專欄: Promise只能進行異步操作?
- 2.4. Promise#then
- 2.5. Promise#catch
- 2.6. 專欄: 每次調用then都會返回一個新創建的promise對象
- 2.7. Promise和數組
- 2.8. Promise.all
- 2.9. Promise.race
- 2.10. then or catch?
- 第三章 - Promise測試
- 3.1. 基本測試
- 3.2. Mocha對Promise的支持
- 3.3. 編寫可控測試(controllable tests)
- 第四章 - Advanced
- 4.1. Promise的實現類庫(Library)
- 4.2. Promise.resolve和Thenable
- 4.3. 使用reject而不是throw
- 4.4. Deferred和Promise
- 4.5. 使用Promise.race和delay取消XHR請求
- 4.6. 什么是 Promise.prototype.done ?
- 4.7. Promise和方法鏈(method chain)
- 4.8. 使用Promise進行順序(sequence)處理
- 第五章 - Promises API Reference
- 5.1. Promise#then
- 5.2. Promise#catch
- 5.3. Promise.resolve
- 5.4. Promise.reject
- 5.5. Promise.all
- 5.6. Promise.race
- 第六章 - 用語集
- 第七章 - 參考網站
- 第八章 - 關于作者
- 第九章 - 關于譯者