如何在 Array.forEach 中正確使用 Async

header

本文譯自How to use async functions with Array.forEach in Javascript - Tamás Sallai

0. 如何異步遍歷元素

第一篇文章中,我們介紹了async / await如何幫助處理異步事件,但在異步處理集合時(shí)卻無濟(jì)于事。在本文中,我們將研究該forEach功能,當(dāng)您需要為集合中的每個(gè)元素運(yùn)行一段代碼時(shí),該功能將非常有用。

1. forEach

forEach函數(shù)類似于map,但是它不轉(zhuǎn)換值并使用結(jié)果,而是為每個(gè)元素運(yùn)行該函數(shù)并丟棄結(jié)果(這里可以理解成是否有return值)。實(shí)際上,重要的部分是調(diào)用函數(shù)的副作用。

例如,將每個(gè)元素同步打印到控制臺:

const arr = [1, 2, 3];

arr.forEach((i) => {
    console.log(i);
});

// 1
// 2
// 3

console.log("Finished sync");
// Finished sync

由于結(jié)果并不重要,因此可以使用異步函數(shù)作為迭代器:

const arr = [1, 2, 3];

arr.forEach(async (i) => {
    // each element takes a different amount of time to complete
    await sleep(10 - i);
    console.log(i);
});

console.log("Finished async");
// Finished async

// 3
// 2
// 1
forEach.png

2. 控制時(shí)間

2.1 等待完成

但是,并不奇怪,該函數(shù)被異步調(diào)用,并且程序執(zhí)行超出了調(diào)用范圍。這是與同步版本的重要區(qū)別,因?yàn)樵趫?zhí)行下一行時(shí),同步forEach已經(jīng)完成,而異步版本尚未完成。這就是為什么“完成的異步”日志出現(xiàn)在元素之前的原因。

要在繼續(xù)進(jìn)行之前等待所有函數(shù)調(diào)用完成,可以使用帶有Promise.allmap,并丟棄結(jié)果:

const arr = [1, 2, 3];

await Promise.all(arr.map(async (i) => {
    await sleep(10 - i);
    console.log(i);
}));

// 3
// 2
// 1

console.log("Finished async");
// Finished async
map.png

進(jìn)行此更改后,“完成的異步操作”排在最后。

2.2 順序處理

但是請注意,迭代函數(shù)是并行調(diào)用的。要忠實(shí)地遵循同步forEach,要先使用帶await memoreduce

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("Finished async");
// Finished async
reduce.png

這樣,元素依次依次處理,程序執(zhí)行將等待整個(gè)數(shù)組完成后再繼續(xù)。

3. 結(jié)論

異步forEach易于使用,但是是否應(yīng)使用forEach,mapreduce取決于計(jì)時(shí)的要求。如果您只想在任何時(shí)候運(yùn)行這些功能,請使用forEach。如果要確保繼續(xù)操作之前完成操作,請使用map。最后,如果您需要一個(gè)一個(gè)地運(yùn)行它們,請使用reduce。

您的關(guān)注是莫大的鼓勵(lì)?(^_-)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容