關於 Promise.all, map, reduce, mapSeries, each 方法


首先加入 bluebird 的 Promise 對象,然后寫一個輔助方法 makePromise 用來生成 Promise ,下面的 data 變量是演示用的數據,代表 setTimeout 的延時。

const Promise = require('bluebird');

function makePromise(name, delay) {
    return new Promise((resolve) => {
        console.log(`${name} started`);
        setTimeout(() => {
            console.log(`${name} completed`);
            resolve(name);
        }, delay);
    });
}

const data = [2000, 1, 1000];

OK,首先看 Promise.all 方法,很簡單,他會等所有 Promise 執行完畢后,把結果放在數組里,注意這里 Promise 的執行不存在什么順序還是並發問題,因為 Promise 本身就代表一個已經執行的過程,所以 Promise.all 就是在等所有過程結束,代碼:

Promise.all(data.map((v, k) => makePromise(k, v))).then(res => {
    console.log(res);
});

輸出:

0 started
1 started
2 started
1 completed
2 completed
0 completed
[ 0, 1, 2 ]

0 started
1 started
2 started
1 completed
2 completed
0 completed
[ 0, 1, 2 ]

然后是 Promise.map 方法,這個相當於把常見的 Array.map 創建 Promise 的過程和 Promise.all 結合起來,所以用 Promise.map 來實現上例的代碼是:

Promise.map(data, (v, k) => makePromise(k, v)).then(res => {
    console.log(res)
});

輸出:

0 started
1 started
2 started
1 completed
2 completed
0 completed
[ 0, 1, 2 ]

輸出和上面的 Promise.all 例子一樣。

另外, Promise.map 還可以加入一個 concurrency 參數,注意這個 concurrency 參數是控制同時並發創建的 Promise 個數,並且是不保證順序的,所以當 {concurrency: 1} 時,只會有一個 Promise 在運行,但是整個數組不保證是從左到右順序執行的。

Promise.reduce 方法才是一個順序執行 Promise 的方法,所謂順序執行,其實就是從左到右按順序去創建 Promise ,並且始終只有一個 Promise 在運行。看 bluebird 的 源碼 ,可以發現,一些順序執行的方法,比如 Promise.mapSeries 和 Promise.each ,都是基於 Promise.reduce 來實現的,這里的 reduce 和 Array.reduce 一樣,測試代碼:

Promise.reduce(data, (total, v, k) => {
    return makePromise(k, v).then(res => {
        return total + res;
    });
}, 0).then(res => {
    console.log(res);
})

輸出:

0 started
0 completed
1 started
1 completed
2 started
2 completed
3

最后的 3 是所有 Promise 的結果總和,即 0+1+2 .

接下來是 Promise.mapSeries 方法,這個方法和 Promise.map 類似,只不過是順序執行的,代碼:

Promise.mapSeries(data, (v, k) => makePromise(k, v), 0).then(res => {
    console.log(res);
})

輸出:

0 started
0 completed
1 started
1 completed
2 started
2 completed
[ 0, 1, 2 ]

最后是 Promise.each 方法,和 Promise.mapSeries 方法類似,都是順序執行,區別是,返回的數組不是所有 Promise 的結果,而是傳入 Promise.each 方法的原始數據數組,如下代碼:

Promise.each(data, (item, index) => makePromise(index, item), 0).then(res => {
    console.log(res);
});

輸出:

0 started
0 completed
1 started
1 completed
2 started
2 completed
[ 0, 1, 2 ]

 

最后還是要看bluebird的文檔,里面還包含了其他好用的方式,比如delay等

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM