2015-04-04 65 views
1

考慮,你必須獲得來自多個異步函數或承諾數據的情況下,什麼是收集和持久化數據,因此它可以全部完成後使用的最佳方法。一個示例情況是多個數據庫查詢需要在單個頁面中呈現。從多個異步功能中收集數據(承諾)

我遇到下面的代碼,它看起來像一個整體圖案給我,但作爲新的異步遊戲我不確定。

function complexQuery(objectId) { 
    var results = {}; 
    return firstQuery.get(objectId).then(function (result1) { 
      results.result1 = result1; 
      return secondQuery.find(); 
     }) 
     .then(function (result2) { 
      results.result2 = result2; 
      return thirdQuery.find(); 
     }) 
     .then(function (result3) { 
      results.result3 = result3; 
      return results; 
     }); 
} 

complexQuery(objectId) 
    .then(function (results) { 
     //can use results.result1, results.result2, results.result3 
     res.render('dash', results); //example use 
    }); 

什麼是處理這種情況的最好方法?

編輯澄清:必須串聯,查詢可能需要來自先前承諾結果的信息。

+0

如果查詢必須是串聯的,您的代碼應該反映這一點。 – Bergi 2015-04-04 12:49:59

+0

有沒有什麼不是由[規範副本](http://stackoverflow.com/q/28250680/1048572)回答的?我傾向於關閉,但隨時編輯並提出更具體的問題 - 可能與您的真實代碼。 – Bergi 2015-04-04 12:51:15

回答

0

最好的辦法是你所有的諾言存儲在數組中,並使用Q.all()或異步相當於我認爲這是運行功能樣樣齊全

+0

只有在承諾不需要彼此的信息時纔會起作用。 – Ryhnn 2015-04-04 11:58:05

+0

您是否使用異步。您可以使用async.series按順序運行,這樣您就可以使用前一個類似於您已有的信息 – Ardenexal 2015-04-04 12:02:23

2

最簡單的方法是使用後的同一Promise.all,它具有並行執行查詢的好處:

function complexQuery(objectId) { 
    return Promise.all([firstQuery.get(objectId), 
         secondQuery.find(), 
         thirdQuery.find()]) 
    .then(([result1, result2, result3] => {result1, result2, result3}); // ES6 syntax 
    /* ES5 equivalent would be 
    .then(function(results) { 
     return {result1: results[0], result2: results[1], result3: results[2]}; 
    }); */ 
} 

如果您需要按順序執行查詢(因爲它們是互相依賴的),看看How do I access previous promise results in a .then() chain?其中不同的策略(如一個給你的問題,其中imo is not a good one)深入解釋。