forEach
函數與 map
類似,可是它不返回結果,而是爲每一個元素運行該函數並丟棄結果。 實際上,重要的部分是調用函數的反作用。數組
例如,將每一個元素同步打印到控制檯異步
const arr = [1, 2, 3]; arr.forEach((i) => { console.log(i); }); // 1 // 2 // 3 console.log("完成同步"); // 完成同步
因爲結果並不重要,所以可使用異步函數做爲迭代器:async
const arr = [1, 2, 3]; arr.forEach(async (i) => { // 每一個元素須要花費不一樣的時間才能完成 await sleep(10 - i); console.log(i); }); console.log("完成異步"); // 完成異步 // 3 // 2 // 1
可是,並不奇怪,該函數被異步調用,而且程序沒有按時間順序完成。 這是與同步版本的重要區別,由於在執行下一行時,同步forEach已完成,而異步版本還沒有完成。 所以,「完成異步」日誌顯示在元素以前。函數
要在繼續進行以前等待全部函數調用完成,請使用帶有 Promise.all
的 map
並不要返回值:spa
const arr = [1, 2, 3]; await Promise.all(arr.map(async (i) => { await sleep(10 - i); console.log(i); })); // 3 // 2 // 1 console.log("完成異步"); // 完成異步
進行此更改後,「完成異步」排在最後。日誌
可是請注意,迭代函數是並行調用的。
若要忠實地遵循同步遍歷,能夠在reduce
中await
累加器,即以下的await memo
:code
const arr = [1, 2, 3]; await arr.reduce(async (memo, i) => { await memo; await sleep(10 - i); console.log(i); }, undefined); // 1 // 2 // 3 console.log("完成異步"); // 完成異步
這樣,元素會依次處理,程序執行將等待整個數組完成後再繼續。blog
異步的數組遍歷很容易使用,可是是用 forEach
,map
或 reduce
取決於時序要求。ip
forEach
。map
。reduce
。