在 JavaScript 的 Promise API 中,要處理一個 Promise 的集合,有 Promise.all()、Promise.any()、…等等,可是這些 API 要嘛要等全部的 Promise 都完成了,要嘛是任一個,而且只有一個 Promise 完成了,才能串接後續的處理,沒有那種依照完成的先後順序一個接一個串接後續處理的 API,不過沒關係,利用 Promise 的特性,我們也是能做到類似的效果。
Promise.all() + map()
Promise 後面串接 then()
方法,會在 Promise 完成的時候呼叫它,利用這個特性,加上 Promise.all() 及 map(),我們可以做出一個接一個先完成先處理的效果。
我的實驗情境是這樣的,我有 5 個 Promises,這 5 個 Promises 個別會在完成的時候,吐出 1 ~ 5 的數字,但是完成的時間不一定。
const promise1 = new Promise((resolve) => setTimeout(resolve, 101, 1));
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 2));
const promise3 = new Promise((resolve) => setTimeout(resolve, 102, 3));
const promise4 = new Promise((resolve) => setTimeout(resolve, 99, 4));
const promise5 = new Promise((resolve) => setTimeout(resolve, 103, 5));
const promises = [promise1, promise2, promise3, promise4, promise5];
然後,我有一個加法器 adder
,依照這 5 個 Promises 完成的先後順序,一一地將結果丟給加法器執行加總,加總完後將結果印出來,這邊我們就需要動用到 Promise.all() 及 map(),直接看下面的程式碼:
const adder = (() => {
let result = 0;
return ((num) => {
if (!num) return result;
console.log(num);
result += num;
return result;
});
})();
Promise.all(promises.map(promise => {
return promise.then(num => adder(num));
})).then(() => {
console.log(adder());
});
預期的結果,應該會依序印出 4、2、1、3、5、15,讓我們看執行結果。
以上,這個將 Promises 依完成的先後順序處理資料的方式,提供給大家參考,如果有朋友有更好的方法,還望不吝告知。