让async/await循环按顺序执行
Make async/await loop execute in order
我有一个看起来像这样的循环:
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 和尽可能少的嵌套来做。
我想通了:
for (let id of newThreadIds) {
let thread = await API.getThread(id);
await ActiveThread.findOneAndUpdate({number: id}, {posts: thread.posts}, {upsert: true}).exec();
await Q.delay(1000);
}
这可能是使用 ES2015 和 async/await 的最佳方式。
map
函数不知道它的回调是异步的并且 return 是一个承诺。它只是立即遍历数组并创建一个承诺数组。你会像
那样使用它
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(或您各自库中的类似内容),它关心每次迭代的承诺 return 值。
在纯 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);
}
我有一个看起来像这样的循环:
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 和尽可能少的嵌套来做。
我想通了:
for (let id of newThreadIds) {
let thread = await API.getThread(id);
await ActiveThread.findOneAndUpdate({number: id}, {posts: thread.posts}, {upsert: true}).exec();
await Q.delay(1000);
}
这可能是使用 ES2015 和 async/await 的最佳方式。
map
函数不知道它的回调是异步的并且 return 是一个承诺。它只是立即遍历数组并创建一个承诺数组。你会像
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(或您各自库中的类似内容),它关心每次迭代的承诺 return 值。
在纯 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);
}