2016-11-19 42 views
0

我在写一个使某个http调用的角度服务。代码是这样的。多个API调用后的角度执行函数

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) 
    }); 
}; 

我需要调用printNotificationsStatus()函数只有在所有API的调用结束,以确保让所有的API响应,但现在被调用的函数在angular.forEach执行结束和API的承诺稍后可以解决,因为它们是异步的。

有没有办法等待?提前 达维德

+0

看一看'$ q.all([承诺...])'https://docs.angularjs.org/api/ng/service/$ q#所有。你需要你的服务来返回一个承诺,以便你可以将它们推送到一个数组。 –

+0

由于布鲁诺和cesaregb注意到我在printNotificationsStatus位置上犯了一个错误......坦克 –

回答

1

您可以使用$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()。

+0

非常感谢! –

1

首先,我注意到你在foreach中有printNotificationsStatus的调用,所以它将被调用多次作为数组中的项。如果这是一个同步过程,它只需要超出forEach。

但是你正在forEach内进行异步调用。 这意味着“主”线程或执行不会等待每个sendNotificationToToken的响应。

在javascript中这种类型的问题有几个很好的模式。 我认为最常见的是@Bruno Pares建议:https://stackoverflow.com/a/40698868/957979

异步库也是一个不错的选择。

但随着回调,你正在使用它,你可以重组的代码来跟踪实际的迭代,而且都完成后,你可以调用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(); 
    } 
    }); 
}); 
+0

非常感谢您的答案! –