如何确保 $http 请求在循环内按顺序执行
How to make sure that $http requests are executed in sequence inside loop
我需要提出 ajax 连锁请求。
function _GetCustomerDetails() {
//Customer
for (var i = 0; i < 5; i++) {
dataService.get(sData, 'Customer').then(function(data) {
if (data.entity === "Customer" && data.rows != undefined && data.rows.length > 0) {
var len = data.rows.length;
for (var i = 0; i < len; i++) {
if (data.rows[i] != undefined) {
//load related entity
dataService.get(data.CustomerId, 'CustomerRelatedEntity').then(function(data) {
});
}
}
}
});
}
}
但是,客户数据加载正常,但嵌套的相关实体加载不正确。它用最后一个填充所有数据。(即,索引=4的客户)
这是我的数据服务的样子。
angular
.module('app')
.service('dataService', dataService);
dataService.$inject = ['$http', '$q'];
function dataService($http, $q) {
var service = {
get: _get,
}
return service;
function _get(data, tableName) {
var deferred = $q.defer();
var url = "API_Url";
return $http({
method: 'GET',
url: url,
})
.then(success)
.catch(exception);
function success(response) {
deferred.resolve(response.data);
return deferred.promise;
}
function exception(ex) {
deferred.reject(response);
return deferred.promise;
}
}
您可以使用像 tj/co 这样的生成器轻松地做到这一点。这样,一旦您的承诺被接受,您的循环步骤就会被转发。如果 data.rows
是 array
.
,此示例将正常工作
function _GetCustomerDetails() {
dataService.get(sData, 'Customer').then(function(data) {
if (data.entity === "Customer" && data.rows != undefined && data.rows.length > 0) {
co(function*() {
for (var i = 0; i < data.rows.length; i++) {
let data = yield new Promise(function(resolve, reject) {
dataService.get(data.rows[i].CustomerId, 'CustomerRelatedEntity').then(function (result) {
resolve(result);
});;
});
console.log(data);
}
});
}
});
}
重现您的问题
看看这个 demo fiddle,它重现了您的问题。如您所见,循环在所有请求响应/完成之前完成。
解决您的问题
看看这个 demo fiddle 这是解决问题和同步循环的一种方法。如您所见,循环等待所有请求完成,然后再开始下一个循环序列。
我需要提出 ajax 连锁请求。
function _GetCustomerDetails() {
//Customer
for (var i = 0; i < 5; i++) {
dataService.get(sData, 'Customer').then(function(data) {
if (data.entity === "Customer" && data.rows != undefined && data.rows.length > 0) {
var len = data.rows.length;
for (var i = 0; i < len; i++) {
if (data.rows[i] != undefined) {
//load related entity
dataService.get(data.CustomerId, 'CustomerRelatedEntity').then(function(data) {
});
}
}
}
});
}
}
但是,客户数据加载正常,但嵌套的相关实体加载不正确。它用最后一个填充所有数据。(即,索引=4的客户)
这是我的数据服务的样子。
angular
.module('app')
.service('dataService', dataService);
dataService.$inject = ['$http', '$q'];
function dataService($http, $q) {
var service = {
get: _get,
}
return service;
function _get(data, tableName) {
var deferred = $q.defer();
var url = "API_Url";
return $http({
method: 'GET',
url: url,
})
.then(success)
.catch(exception);
function success(response) {
deferred.resolve(response.data);
return deferred.promise;
}
function exception(ex) {
deferred.reject(response);
return deferred.promise;
}
}
您可以使用像 tj/co 这样的生成器轻松地做到这一点。这样,一旦您的承诺被接受,您的循环步骤就会被转发。如果 data.rows
是 array
.
function _GetCustomerDetails() {
dataService.get(sData, 'Customer').then(function(data) {
if (data.entity === "Customer" && data.rows != undefined && data.rows.length > 0) {
co(function*() {
for (var i = 0; i < data.rows.length; i++) {
let data = yield new Promise(function(resolve, reject) {
dataService.get(data.rows[i].CustomerId, 'CustomerRelatedEntity').then(function (result) {
resolve(result);
});;
});
console.log(data);
}
});
}
});
}
重现您的问题
看看这个 demo fiddle,它重现了您的问题。如您所见,循环在所有请求响应/完成之前完成。
解决您的问题
看看这个 demo fiddle 这是解决问题和同步循环的一种方法。如您所见,循环等待所有请求完成,然后再开始下一个循环序列。