javascript - 使异步/等待循环按顺序执行

标签 javascript node.js async-await ecmascript-next

我有一个看起来像这样的循环:

    newThreadIds.map(async function(id) {
      let thread = await API.getThread(id);
      await ActiveThread.findOneAndUpdate({number: id}, {posts: thread.posts}, {upsert: true}).exec();
      await Q.delay(1000);
    });

问题是每次迭代都是异步执行的,我希望它们之间有 1 秒的延迟。我知道如何用 promises 来做,但它看起来很难看,我更愿意用 async/await 和尽可能少的嵌套来做。

最佳答案

map 函数不知道它的回调是异步的并返回一个 promise 。它只是立即遍历数组并创建一个 promise 数组。你会像这样使用它

const promises = newThreadIds.map(async function(id) {
    const thread = await API.getThread(id);
    return ActiveThread.findOneAndUpdate({number: id}, {posts: thread.posts}, {upsert: true}).exec();
});
const results = await Promise.all(promises);
await Q.delay(1000);

对于顺序执行,您需要使用 Bluebird's mapSeries function (或来自您各自库的类似内容),它关心每次迭代的 promise 返回值。

在纯 ES6 中,您必须使用一个实际的循环,其控制流将遵循循环体中的 await 关键字:

let results = [];
for (const id of newThreadIds) {
    const thread = await API.getThread(id);
    results.push(await ActiveThread.findOneAndUpdate({number: id}, {posts: thread.posts}, {upsert: true}).exec());
    await Q.delay(1000);
}

关于javascript - 使异步/等待循环按顺序执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35632531/

相关文章:

WPF:调用线程无法访问此对象,因为不同的线程拥有它

c# - 异步并等待 For 循环

javascript - 如何防止用户在 Angular 2 的文本框中粘贴错误的值?

javascript - PhantomJs 在渲染 pdf 时将页眉边距设置为 0

javascript - webpack+babel npm 不想启动

node.js - 来自 Lambda 的 REST 调用通常非常慢

c# - 以正确的方式在异步方法中连接三个任务的结果

javascript - Chrome JavaScript 位置对象

javascript - Node JS : File upload Error [ERR_STREAM_WRITE_AFTER_END]

php - 使用 knockout.js 和 php 检查输入