如何在Javascript中對陣列的遍歷使用非同步函式
阿新 • • 發佈:2020-09-19
陣列遍歷
forEach函式與map相似,但是它不返回結果,而是為每個元素執行該函式並丟棄結果。 實際上,重要的部分是呼叫函式的副作用。
例如,將每個元素同步列印到控制檯
const arr = [1, 2, 3];
arr.forEach((i) => {
console.log(i);
});
// 1
// 2
// 3
console.log("完成同步");
// 完成同步
由於結果並不重要,因此可以使用非同步函式作為迭代器:
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並不要返回值:
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:
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("完成非同步");
// 完成非同步
這樣,元素會依次處理,程式執行將等待整個陣列完成後再繼續。
品牌vi設計公司http://www.maiqicn.com 辦公資源網站大全https://www.wode007.com
結論
非同步的陣列遍歷很容易使用,但是是用forEach,map或reduce取決於時序要求。
- 如果你只想在任何時候執行這些功能,請使用forEach。
- 如果要確保繼續操作之前完成操作,請使用map。
- 如果你需要一個一個地執行它們,請使用reduce。