簡體   English   中英

使用 async/await 承諾以“並行”方式運行 for 循環

[英]Running for loop in “parallel” using async/await promises

我目前有一個這樣的for循環:

async myFunc() {
    for (l of myList) {
        let res1 = await func1(l)
        if (res1 == undefined) continue

        let res2 = await func2(res1)
        if (res2 == undefined) continue

        if (res2 > 5) {
            ... and so on
        }
    }
}

問題是 func1, func2 是返回承諾的網絡調用,我不希望它們在等待它們時阻塞我的 for 循環。 所以我不介意與 myList[0] 和 myList[1] 並行工作,也不關心列表項的處理順序。

我怎樣才能做到這一點?

我會通過編寫一個 function 來處理您正在按順序處理的一個值:

async function doOne(l) {
    let res1 = await func1(l);
    if (res1 == undefined) {
        return /*appropriate value*/;
    }

    let res2 = await func2(res1);
    if (res2 == undefined) {
        return /*appropriate value*/;
    }

    if (res2 > 5) {
        // ... and so on
    }
}

然后我會使用Promise.allmap來啟動所有這些並讓它們並行運行,將結果作為數組獲取(如果您需要結果):

function myFunc() {
    return Promise.all(myList.map(doOne)); // Assumes `doOne` is written expecting to be called via `map` (e.g., won't try to use the other arguments `map` gives it)
    // return Promise.all(myList.map(l => doOne(l))); // If we shouldn't make that assumption
}

如果myList是(或可能是)非數組可迭代對象,請使用Array.from獲取數組以在以下位置使用map

function myFunc() {
    return Promise.all(Array.from(myList.map(doOne)));
}

(或使用for-of循環推送到數組。)

如果您不希望無法處理列表中的一個條目以防止看到處理列表中其他條目的結果,請使用Promise.allSettled而不是Promise.all (請注意,它們都會以任何一種方式啟動,唯一的區別是當至少其中一個失敗時您是否看到成功的結果。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM