2015-04-04 64 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)深入解释。