我有以下函数从HTML中的ng-click
执行:
vm.items = [];
vm.moveItems = function() {
angular.forEach(vm.items,
function (item) {
$http({
method: 'PUT',
url: '/api/item_move/' + item.id}
}).then(function(response) {
Toast.success("Successfully moved item " + item.id);
vm.reload();
}, function (error) {
Toast.error("Failed to move item " + item.id, error);
});
});
};
现在,问题是vm.reload()
在每次成功响应之后执行,实际上如果在整个forEach
完成后执行一次就足够了。我对JS中的异步编程很新,所以想知道最常用的解决方法是什么。
答案 0 :(得分:2)
创建一个数组,用于存储HTTP调用的promise。然后调用Promise.all()
方法。这允许你在所有承诺完成后做一些事情。
vm.items = [];
vm.moveItems = function() {
var promises = [];
angular.forEach(vm.items,
function (item) {
promises.push($http({
method: 'PUT',
url: '/api/item_move/' + item.id}
}));
});
Promise.all(promises)
.then(function() {
vm.reload();
});
};
修改:由于您使用的是AngularJS,因此您也可以执行$q.all()
。
答案 1 :(得分:0)
你可以这样做:
vm.items = [];
vm.moveItems = function() {
var i = 0
angular.forEach(vm.items,
function (item) {
$http({
method: 'PUT',
url: '/api/item_move/' + item.id}
}).then(function(response) {
Toast.success("Successfully moved item " + item.id);
i++;
if(i == vm.items.length{ // execute only when its the last loop of foreach
vm.reload();
}
}, function (error) {
i++;
if(i == vm.items.length{ // execute only when its the last loop of foreach
vm.reload();
}
Toast.error("Failed to move item " + item.id, error);
});
});
};
答案 2 :(得分:0)
解决方案:
vm.items = [];
vm.moveItems = function() {
var promises = [];
angular.forEach(vm.items , function(item) {
var promise = $http({
method: 'PUT',
url: '/api/item_move/' + item.id}
}).then(function(response) {
Toast.success("Successfully moved item " + item.id);
}, function (error) {
Toast.error("Failed to move item " + item.id, error);
});
promises.push(promise);
});
$q.all(promises).then(function() { vm.reload() })
});
答案 3 :(得分:-1)
将vm.reload()移到forEach循环之外:
vm.items = [];
vm.moveItems = function() {
this._$timeout(() => {
angular.forEach(vm.items,
function (item) {
$http({
method: 'PUT',
url: '/api/item_move/' + item.id}
}).then(function(response) {
Toast.success("Successfully moved item " + item.id);
}, function (error) {
Toast.error("Failed to move item " + item.id, error);
});
});
});
vm.reload();
};
编辑添加$ timeout,应该给它足够的时间来完成foreach循环。