Nodejs顺序运行promises

时间:2015-11-16 09:26:16

标签: node.js express promise

亲爱的,

我如何按顺序在nodejs中运行promises,在下面的示例中循环遍历数小时数组,然后为每个获取的小时从数据库获取结果,问题在于:我得到的结果但是我想要它顺序相同的顺序我得到了小时 。

angular.forEach(SharedVar.getCategories(), function (h) {
                                        t = h.split('-', 2);
                                        t = t[0];
                                        RESTApi.getAnswerdCallsByHour(t).then(function (answerdTotal) {
                                                $scope.answerdCallsTotalByHour.push(answerdTotal);
                                                var d = SharedVar.getDataS();
                                                d[count] = answerdTotal;
                                                SharedVar.setDataS(d);

                                                count++;

                                        });

                                });

谢谢,

3 个答案:

答案 0 :(得分:0)

执行此操作的方法是执行一个请求并在承诺中执行下一个请求。

我认为到目前为止更好的方法是以某种方式扩展您的SharedVar.setDataS(d)函数,它不依赖于按顺序获取数据。就像拥有SharedVar.setDataS(d,index)并在RESTApi中使用$ http.get(或其他)函数调用中的config var一样,将索引一直提升到promise。

如果你的RESTApi看起来像这样:

var RESTApi = {
  getAnswerdCallsByHour : function(hour) {
    var url = "bla.com/myservice?hour=" + hour;
    return $http.get(url).data;
  }
  // Some other Methods...

然后你需要一种方法来传递一些东西,以便在数据异步到达时“重新排序”你的数据,这可能是你计算的索引,或者在你的情况下可能是小时变量:

  var RESTApi = {
  getAnswerdCallsByHour : function(hour) {
    var url = "bla.com/myservice?hour=" + hour;
    var config = [];
    config.hour = hour;
    return $http.get(url, config); // Return the promise not just data or a specific field
  }
  // Some other Methods...

现在,当您的承诺已完整填写时,您可以像这样访问“小时”变量:

var d = SharedVar.getDataS();
d[promise.config.hour] = promise.data;
SharedVar.setDataS(d);

现在您知道哪些数据与哪个请求相关,您无需按顺序接收数据。最后一块仅在小时从0到23连续运行时才能正常工作,如果不是这种情况,则需要:

  var RESTApi = {
  getAnswerdCallsByHour : function(hour, index) {
    var url = "bla.com/myservice?hour=" + hour;
    var config = [];
    config.index = index;
    return $http.get(url, config);
  }
  // Some other Methods...
  ...
  ...
  var d = SharedVar.getDataS();
  d[promise.config.index] = promise.data;
  SharedVar.setDataS(d);

答案 1 :(得分:0)

var promise = Promise.resolve(); // make an empty promise in the way you do it with your promise library
angular.forEach(SharedVar.getCategories(), function (h) {

   promise.then(function() {
       return RESTApi.getAnswerdCallsByHour(t).then(function (answerdTotal) {});
   });

});

答案 2 :(得分:0)

Safari的答案就是我通常如何处理这个问题。 (对不起,我还没有足够的代表发表评论......)您遇到了问题,因为提供的示例没有捕获并在后续循环中使用新的承诺。请点击我对稍加修改版本的评论:

    var promise = Promise.resolve();
    angular.forEach(SharedVar.getCategories(), function (h) {
        t = h.split('-', 2);
        t = t[0];

        // You must capture the new promise here; the next loop will wait
        // for the promise returned from getAnswerdCallsByHour to resolve.
        promise = promise.then(function() {
            // Halt downstream promises until this returned promises finishes
            return RESTApi.getAnswerdCallsByHour(t).then(function (answerdTotal) {
                $scope.answerdCallsTotalByHour.push(answerdTotal);
                var d = SharedVar.getDataS();
                d[count] = answerdTotal;
                SharedVar.setDataS(d);

                count++;
            });
        });
    });