繁体   English   中英

promise.then() 在 for 循环中顺序运行

[英]promise .then() to run sequentially inside a for loop

我正在尝试通过多个连续的 API 调用依次填充我的$scope.results = [] 顺序很重要,因为我要传递一个开始和一个限制数字(类似于分页)。 由于 API 网关在 30 秒后超时,我无法在 1 次调用中执行此操作并且需要中断多次调用是有原因的。

我的问题是在 for 循环中它不能按顺序工作。 在数组内部,all.network 请求似乎获得了相同的start ,并且没有按顺序发送。 我也不能使用async/await 有没有办法按顺序运行 API 调用并将结果添加到results数组。 我的最终目标是像在单个 API 调用中发生的那样填充数组,但有多个调用

         $scope.detailedReportOfAll = function () {
            $scope.start = 0;
            $scope.limit = 15;
            $scope.results = [];
            var requestCount = 1;
            APIService.getDetailedReportData($scope.start,$scope.limit).then(
              function ({result,nbPages}) {
                if (result.length){
                  $scope.results = $scope.results.concat(result);
                  requestCount ++;
                  $scope.start += $scope.limit;
                }
                if (requestCount < nbPages){ //I'm running the loop for (nbPages - 1) times

                  for (i=2; i<nbPages; i++){
                    APIService.getDetailedReportData($scope.start,$scope.limit).then(
                      function ({result,nbPages}) {
                        if (result.length){
                          $scope.results = $scope.results.concat(result);
                          requestCount ++;
                          console.log($scope.results, requestCount)
                          $scope.start += $scope.limit;
                        }
                      })
                  }
                }
              }
            );
          };

这是我的 http 呼叫 function。它返回 promise

    var getDetailedReportData= function (start, limit) {
      $rootScope.isLoading = true;
      var deferred = $q.defer();
      $http
        .get(rootURL('/getAllReports/'+start+'/'+limit))
        .success(function (response) {
          deferred.resolve(response);
        })
        .catch(function (err) {
          deferred.reject(err);
        })
        .finally(function () {
          $rootScope.isLoading = false;
        });
      return deferred.promise;
    };

非常感谢帮助

如果你想连续运行这些,那么当你知道 async function n-1完成时,你需要触发 async function n 即在then回调中。 如果您拒绝了asyncawait ,递归调用 function 可能是最简单的方法。

 function somethingAsync(value) { return new Promise(res => setTimeout(res, 500, value * value)); } function processInputInSeries(input) { function processNext(index, input, results) { if (index >= input.length) return results; return somethingAsync(input[index]).then(function (result) { return processNext(index + 1, input, [...results, result]); }); } return processNext(0, input, []); } const resultPromise = processInputInSeries([1,2,3]); resultPromise.then(function(results) { console.log(results) });

相比之下, async / await更清晰:

 function somethingAsync(value) { return new Promise(res => setTimeout(res, 500, value * value)); } async function processInputInSeries(input) { let results = []; for (let i = 0; i < input.length; i++) { const result = await somethingAsync(input[i]); results = [...results, result]; } return results; } const resultPromise = processInputInSeries([1,2,3]); resultPromise.then(function(results) { console.log(results) });

即使您最终使用 Babel 来转换您的 JS 以与过时的系统兼容,我也会建议您以这种方式编写它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM