[小菜一碟] 在 JavaScript 依照 Resolve 的順序處理 Promise

在 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 依完成的先後順序處理資料的方式,提供給大家參考,如果有朋友有更好的方法,還望不吝告知。

參考資料

C# 指南ASP.NET 教學ASP.NET MVC 指引
Azure SQL Database 教學SQL Server 教學Xamarin.Forms 教學