簡體   English   中英

為什么 for...of 等待 Promise 解決而 .forEach() 沒有?

[英]Why for…of waits for Promise to resolve and .forEach() doesn't?

在處理 Promises 的情況下,我很難理解for...of.forEach()的不同之處。

使用這個片段:

const allSettled = async arr => {
    const data = []

    for (const promise of arr) {
        try {
            const result = await promise;
            data.push(result);
        } catch (e) {
            data.push(e)
        }
    }

    return data
}

I go 在數組中的每個 promise 上,等待它解決並將結果推送到data 它按順序執行。

如果我有這個片段:

const badAllSettled = arr => {
    const data = []

    arr.forEach(async promise => {
        try {
            const result = await promise;
            data.push(result);
        } catch (e) {
            data.push(e)
        }
    })

    return data
}

我得到空數組(因為forEach不等待 Promise 解決)。

AFAIK for...of適用於可迭代對象,因此它可能會暫停並等待await返回。 但是我不明白這個流程是如何一步一步地工作的。

謝謝!

.forEach()是這樣實現的:

Array.prototype.forEach = function forEach(fn) {
  for (let i = 0; i < this.length; i++)
    fn(this[i], i, this);
}

如您所見,當.forEach()時,它只是同步調用了幾次回調。 但是,如果回調是異步 function,則不會等待。

相比之下,當在 async function 中找到await關鍵字時,與 function 相關的所有代碼執行都將暫停,直到 promise 解決循環,這也意味着任何暫停for... of控制流。

The following code behaves like .forEach() because it calls the async function which awaits the promise without awaiting the promise the function returns:

const allSettled = async arr => {
    const data = []

    for (const promise of arr) {
        (async () => {
            try {
                 const result = await promise;
                 data.push(result);
            } catch (e) {
                data.push(e)
            }
        )();
    }

    return data
}

for...of不等待。 await關鍵字進行等待。 你在這里有一個: const result = await promise;

forEach的內部不會await您傳遞給forEach(here)的 function 返回的 promise 。 (在生成 promise 的 function 中使用await是無關緊要的)。

for (const item of array) {
  // do something
}

為數組的每個元素做“某事”。 如果您在內部await某些內容,它將等待它,直到繼續執行代碼的 rest。

array.forEach(callback)

為數組的每個元素同步調用回調。 如果您的回調恰好是異步的,它將調用它,然后立即調用下一個回調。 .forEach在調用下一個回調之前不會等待每個回調解決某個問題。


請注意,如果您希望您的承諾並行運行,也許是為了提高性能,您可能想使用Promise.all

// runs every fetch sequentially
// if each of them takes 1s, this will take 3s to complete
const results = []
for (const item of [1,2,3]) {
  results.push(await fetchSomething(item))
}

// runs every fetch in parrallel
// if each of them takes 1s, this will take 1s to complete
const promises = [1,2,3].map(item => fetchSomething(item))
const results = await Promise.all(promises)

暫無
暫無

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

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