繁体   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