2016-02-25 78 views
2

执行我有一个循环,看起来像这样:制作异步/等待环路为了

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秒的延迟。我知道如何用promise做到这一点,但它看起来很丑,我宁愿用async/await和尽可能少的嵌套来做。

回答

4

我已经想通了:

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和异步/的await。

5

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(或从各自的库类似的东西)来代替,该在乎每一次迭代的承诺返回值。

在纯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); 
}