【问题标题】:Nodejs run promises sequentiallyNodejs 按顺序运行 Promise
【发布时间】:2016-02-17 08:27:34
【问题描述】:

亲爱的,

如何在 nodejs 中按顺序运行 Promise,在下面的示例中,我循环遍历小时数组,然后对于每个获取的小时从数据库中获取结果,这里的问题:正在获取结果,但我希望它按顺序与我得到的顺序相同小时 。

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++;

                                        });

                                });

谢谢,

【问题讨论】:

    标签: node.js express promise


    【解决方案1】:
    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】:

    依次执行此操作的方法是执行一个请求并在 Promise 中执行下一个请求。

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

    如果您的 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);
    

    【讨论】:

    • 我已经尝试过你的建议,仍然面临同样的问题。我所做的是将索引传递给 SharedVar.setData(d,index) 。关于 RESTApi 只是从数据库中获取数据并返回计数。
    • 是的,如果你明白我想说的话,不完全是舒尔。我在答案中添加了一些代码。
    【解决方案3】:

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

        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++;
                });
            });
        });
    

    【讨论】:

      猜你喜欢
      • 2020-06-16
      • 2017-04-19
      • 1970-01-01
      • 1970-01-01
      • 2015-10-02
      • 2021-11-14
      • 1970-01-01
      • 2017-11-16
      • 2022-01-18
      相关资源
      最近更新 更多