2016-02-25 113 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); 
}