簡體   English   中英

如何在循環中等待 promise 完成? (不使用異步等待)

[英]How do I wait for a promise to finish inside a loop? (without using async-await)

下面的代碼只等待 for 循環的第一次迭代。 如果我使用異步等待,它工作正常。 那么我在哪里錯了?

function wait(milliseconds) {
  return new Promise(resolve => setTimeout(resolve, milliseconds))
}

function countDown(count) {
  for (let i = count; i > 0; i--) {
    wait(1000)
      .then(() => console.log(i))
      .catch((error) => console.log(error));
  }
}

countDown(5);

因為 Promise 在完成任務時會運行“then”語句。 如果你像這樣使用循環,i=4 的 Promise 將在 i=5 執行后立即執行。 這將使輸出只等待第一個。

解決方案是在使用遞歸函數完成 Promise (i=5) 之后運行 Promise (i=4)。

function wait(milliseconds) {
    return new Promise(resolve => setTimeout(resolve, milliseconds))
}

function countDown(count) {
    if (count === 0) return;
    wait(1000)
        .then(() => {
            console.log(count)
            countDown(count - 1)
        })
        .catch((error) => console.log(error));
}

countDown(5);

當你在Promise上調用then時,執行不會停止,就像你使用await時一樣。 在第一個循環中,創建了一個Promise ,其then方法將在一秒鍾內執行,但該函數繼續循環,因為執行尚未停止。 在循環結束時,您有五個Promise對象,它們都是連續創建的,中間沒有停頓,因此它們的一秒超時都執行得非常接近。

這是await方法,帶有一個注釋,指出執行停止的位置。

function wait(milliseconds) {
    return new Promise(resolve => setTimeout(resolve, milliseconds));
}

async function countDown(count) {
    for (let i = count; i > 0; i--) {
        await wait(1000); // Execution stops here for one second before continuing
        console.log(i);
    }
}

countDown(5);

這是更接近Phúc Đỗ Vương 的回答的內容,其中有一條評論指出執行不會停止。

function wait(milliseconds) {
    return new Promise(resolve => setTimeout(resolve, milliseconds));
}

function countDown(count) {
    if (count === 0) {
        return;
    }
    
    wait(1000).then(() => {
        // This code, including the next call to countDown, will execute in one second
        console.log(count);
        countDown(count - 1);
    });

    // The current call to countDown finishes before the next call begins
}

countDown(5);

暫無
暫無

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

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