我发送多个HTTP调用来更新foreach循环内的项目,并在所有请求完成后需要回调。我找到this但没有帮助。
我的代码:
$q.all(_($scope.students.items).each(function(item) {
$scope.student.update(); //this is an http call
})).then(function() {
// I need a callback need here
alert("complete"); //should be shown after all students get updated but it is
// called before all network calls got complete
});
这是通用更新功能
self.update = function(item, callback) {
that.post(item, self.getUrl("update") , function(err, data) {
if (self.formatter) {
data = self.formatter(data);
}
callback(err, data);
});
};
有什么建议吗?
答案 0 :(得分:1)
您错过return
函数中的update()
关键字,因为它必须返回一个承诺(当然,that.post()
函数也必须返回一个承诺):
self.update = function(item, callback) {
return that.post(item, self.getUrl("update") , function(err, data) {
if (self.formatter) {
data = self.formatter(data);
}
callback(err, data);
});
};
然后这应该有效:
var promises = [];
_($scope.students.items).each(function(item) {
promises.push($scope.student.update());
})
$q.all(promises).then(function() {
alert("complete");
});
答案 1 :(得分:1)
您也可以使用map
$q.all(_($scope.students.items).map(function(item) {
item.update();
})).then(function() {
alert("complete");
});
我已使用以下代码段更新了此处的代码。我使用了一些返回简单承诺的方法。包括两种方法可以做到这一点。
angular.module('demoApp', []).controller('DemoController', function($scope, $q, $timeout) {
var a = function() {
var deferred = $q.defer();
console.log('Executing a');
deferred.resolve();
return deferred.promise;
};
var b = function() {
var deferred = $q.defer();
console.log('Executing b');
deferred.resolve();
return deferred.promise;
};
var c = function() {
var deferred = $q.defer();
console.log('Executing c');
deferred.resolve();
return deferred.promise;
};
var f = [{
call: a
}, {
call: b
}, {
call: c
}];
$scope.mapTest = function() {
$q.all(f.map(function(item) {
return item.call();
})).then(function() {
console.log("complete");
});
};
$scope.promisePush = function() {
var promises = [];
angular.forEach(f, function(item) {
promises.push(item.call());
});
$q.all(promises).then(function() {
console.log('complete');
});
};
});

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="demoApp">
<div ng-controller="DemoController">
<button ng-click="mapTest()">Q.all using map</button>
<button ng-click="promisePush()">Q.all using promise push</button>
</div>
</body>
&#13;
答案 2 :(得分:1)
$q.all(_.map($scope.students.items, function(item) {
return item.update();
})).then(function() {
//everything has completed
});
$scope.student.items
中每个项目的更新功能必须返回此功能的承诺。类似的东西:
function update() {
return $http( ... );
}
答案 3 :(得分:0)
你不应该在foreach中发送相同的ajax。这应该是单个ajax并且更新应该在回调中完成,因此发送一个类似“studentsUpdate”的ajax并作为响应在foreudenst收集和更新对象数据上做foreach。良好做法是减少ajax呼叫。