[英]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
回调中。 如果您拒绝了async
和await
,递归调用 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.