Javascript 在多次API调用后执行函数
我正在编写一个angular服务来进行一些http调用。 代码是这样的Javascript 在多次API调用后执行函数,javascript,angularjs,api,asynchronous,promise,Javascript,Angularjs,Api,Asynchronous,Promise,我正在编写一个angular服务来进行一些http调用。 代码是这样的 this.checkAndSendNotifications = function() { UsersService.getArray(function(array) { var notifications = []; angular.forEach(array, function(element) { if (some conditions is true) {
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您可以使用它等待所有承诺得到解决。像这样:
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()。您可以使用等待所有承诺得到解决。像这样:
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()。首先,我注意到您在foreach中调用了
printNotificationsStatus
,因此它将被调用的次数与数组中的项相同。如果这是一个同步过程,那么它只需要在forEach之外
但是您正在forEach中进行异步调用。
这意味着“主”线程或执行不会等待每个sendNotificationToToToToToken
的响应
对于javascript中的这类问题,有几种很好的模式。
我认为最常见的是@Bruno Pares建议的:
异步库也是一个不错的选择
但是使用当前使用的回调,您可以重新构造代码以跟踪实际的迭代,并且在完成之后,您可以调用printNotificationsStatus
我认为这个答案完全适用于你的问题。
[所述链接中的代码]:
function callback () { console.log('all done'); }
var itemsProcessed = 0;
[1, 2, 3].forEach((item, index, array) => {
asyncFunction(item, () => {
itemsProcessed++;
if(itemsProcessed === array.length) {
callback();
}
});
});
首先,我注意到您在foreach中调用了
printNotificationsStatus
,因此它将被调用的次数与数组中的项相同。如果这是一个同步过程,那么它只需要在forEach之外
但是您正在forEach中进行异步调用。
这意味着“主”线程或执行不会等待每个sendNotificationToToToToToken
的响应
对于javascript中的这类问题,有几种很好的模式。
我认为最常见的是@Bruno Pares建议的:
异步库也是一个不错的选择
但是使用当前使用的回调,您可以重新构造代码以跟踪实际的迭代,并且在完成之后,您可以调用printNotificationsStatus
我认为这个答案完全适用于你的问题。
[所述链接中的代码]:
function callback () { console.log('all done'); }
var itemsProcessed = 0;
[1, 2, 3].forEach((item, index, array) => {
asyncFunction(item, () => {
itemsProcessed++;
if(itemsProcessed === array.length) {
callback();
}
});
});
看看
$q.all([承诺…])
。您需要您的服务返回一个承诺,这样您就可以将它们推送到阵列中。正如Bruno和cesaregb注意到我在printNotificationsStatus位置上犯了一个错误。。。看看$q.all([承诺…])
。您需要您的服务返回一个承诺,这样您就可以将它们推送到阵列中。正如Bruno和cesaregb注意到我在printNotificationsStatus位置上犯了一个错误。。。坦克