在 for 循环中按顺序承诺 .then() 到 运行
promise .then() to run sequentially inside a for loop
我正在尝试通过多个顺序 API 调用顺序填充我的 $scope.results = []
。顺序很重要,因为我要传递一个开始和一个限制数字(类似于分页)。由于 API 网关在 30 秒后超时,我无法在 1 个调用中执行此操作并且需要分成多个调用是有原因的。
我的问题是 for 循环无法按顺序工作。在数组内部,所有网络请求似乎都获得相同的 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调用函数。它returns一个承诺
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;
};
非常感谢帮助
如果你想运行这些串联,那么当你知道异步函数n-1[时,你需要触发异步函数n =37=]完成;即在 then
回调中。如果您拒绝 async
和 await
.
,递归调用函数可能是最简单的方法
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 以与过时的系统兼容,我也建议您这样写。
我正在尝试通过多个顺序 API 调用顺序填充我的 $scope.results = []
。顺序很重要,因为我要传递一个开始和一个限制数字(类似于分页)。由于 API 网关在 30 秒后超时,我无法在 1 个调用中执行此操作并且需要分成多个调用是有原因的。
我的问题是 for 循环无法按顺序工作。在数组内部,所有网络请求似乎都获得相同的 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调用函数。它returns一个承诺
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;
};
非常感谢帮助
如果你想运行这些串联,那么当你知道异步函数n-1[时,你需要触发异步函数n =37=]完成;即在 then
回调中。如果您拒绝 async
和 await
.
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 以与过时的系统兼容,我也建议您这样写。