我正在编写一个角色服务来进行一些http调用。 代码是这样的。
this.checkAndSendNotifications = function() {
UsersService.getArray(function(array) {
var notifications = [];
angular.forEach(array, function(element) {
if (some conditions is true) {
srv.sendNotificationToToken(element.id,
function() {
notifications.push({
id: user.id,
errorStatus: null,
errorStatusText: null
});
},
function(error) {
notifications.push({
id: user.id,
errorStatus: error.status,
errorStatusText: error.statusText
});
});
}
});
printNotificationsStatus(notifications);
});
};
this.sendNotificationToToken = function(id, onSuccess, onError) {
$http({
method: 'POST',
url: 'https://url....',
headers: {
'Authorization': 'Bearer ....',
'Content-Type': 'application/json'
},
data: {
"id": id,
"message": "hello"
}
}).then(function successCallback(response) {
onSuccess();
}, function errorCallback(error) {
onError(error)
});
};
我只需要在所有api调用结束时调用printNotificationsStatus()函数,以确保所有api响应,但现在函数在angular.forEach执行结束时被调用,API的承诺可以在以后解决因为它们是同步的。
有没有办法等待?
提前致谢 的Davide
答案 0 :(得分:2)
您可以使用$q.all等待所有承诺得到解决。像这样:
UsersService.getArray(function(array) {
var promises = [];
var notifications = [];
angular.forEach(array, function(element) {
if (some conditions is true) {
var promise = srv.sendNotificationToToken(element.id,
function() {
notifications.push({
id: user.id,
errorStatus: null,
errorStatusText: null
});
},
function(error) {
notifications.push({
id: user.id,
errorStatus: error.status,
errorStatusText: error.statusText
});
});
promises.push(promise);
}
});
// wait all promises and resolve
$q.all(promises).then(function () {
printNotificationsStatus(notifications);
})
});
};
不要忘记注入$ q。
Ps:在你的代码中,你在第一次迭代后执行printNotificationsStatus()。
答案 1 :(得分:2)
首先,我注意到您在foreach中呼叫printNotificationsStatus
,因此它将作为阵列中的项目被调用多次。如果这是一个同步过程,它只需要超出forEach。
但是你在forEach中进行异步调用。
这意味着"主要"线程或执行不会等待每个sendNotificationToToken
的响应。
javascript中存在一些针对此类问题的好模式。 我认为最常见的是@Bruno Pares建议:https://stackoverflow.com/a/40698868/957979
Async库也是一个不错的选择。
但是当您正在使用回调时,您可以重新构建代码以跟踪实际迭代,并且在完成后,您可以调用printNotificationsStatus
这个答案我觉得完全适用于你所要求的。
https://stackoverflow.com/a/18983245/957979
[提及链接的代码]:
function callback () { console.log('all done'); }
var itemsProcessed = 0;
[1, 2, 3].forEach((item, index, array) => {
asyncFunction(item, () => {
itemsProcessed++;
if(itemsProcessed === array.length) {
callback();
}
});
});