简体   繁体   English

AngularJS等待foreach内部的所有异步调用

[英]AngularJS wait for all async calls inside foreach finish

I am looping through an array with angular.forEach and calling a non-angular ajax library (Trello client.js). 我使用angular.forEach循环遍历数组并调用非角度ajax库(Trello client.js)。 The client does have 'success' and 'error' callbacks, but doesn't return an angular deferred. 客户端确实有“成功”和“错误”回调,但不会返回角度延迟。 I would like to execute a function once all of the ajax calls have completed. 所有ajax调用完成后,我想执行一个函数。

I have the following code: 我有以下代码:

$scope.addCards = function(listId)
            {
                var cardTitles = $scope.quickEntryCards[listId].split('\n');
                angular.forEach(cardTitles, function(cardTitle,key)
                {
                    Trello.post('/cards', {
                        name:cardTitle,
                        idList:listId
                    },function(){ }, function(){ });
                });
                //TODO: wait for above to complete...
                $scope.init($routeParams.boardId);  
                $scope.quickEntryCards[listId] = '';    
            };

What can I do at that //TODO and in the callback functions so that the last 2 lines only run after all the posts either succeed or fail? 我可以在// TODO和回调函数中做什么,以便最后2行只在所有帖子成功或失败后运行?

pseudo code using angular's $q service. 使用angular的$ q服务的伪代码。

requests = [];

forEach cardTitle
   var deferred = $q.defer();
   requests.push(deferred);
   Trello.post('/path', {}, deferred.resolve, deferred.reject);

$q.all(requests).then(function(){
    // TODO
});

For those looking for the answer to the question's title "AngularJS wait for all async calls inside foreach finish" , here is a generic way to achieve it, also using angular's $q service: 对于那些寻找问题标题“AngularJS等待foreach结束内所有异步调用”的答案的人来说,这是实现它的通用方法,也使用angular的$ q服务:

$scope.myArray = [1, 2, 3, 4, 5, 4, 3, 2, 1];
var loopPromises = [];
angular.forEach($scope.myArray, function (myItem) {
    var deferred = $q.defer();
    loopPromises.push(deferred.promise);
    //sample of a long-running operation inside loop...
    setTimeout(function () {
        deferred.resolve();
        console.log('long-running operation inside forEach loop done');
    }, 2000);

});
$q.all(loopPromises).then(function () {
    console.log('forEach loop completed. Do Something after it...');
});

Here is a working sample . 这是一个工作样本

Have a look at the async library https://github.com/caolan/async . 看看异步库https://github.com/caolan/async

So you can either run all your asyn functions in parallel or series and your common callback will be executed once all of them are finished. 因此,您可以并行或串行运行所有的asyn函数,并且一旦完成所有函数,就会执行常见的回调函数。

async.parallel([
    function(){ ... },
    function(){ ... }
], callback);

async.series([
    function(){ ... },
    function(){ ... }
]);

Hope it helps. 希望能帮助到你。

Simply , you can do like this 简单地说,你可以这样做

var jsonArray3=[];
angular.forEach($scope.jsonArray1,function(value,key){
    angular.forEach(jsonArray2,function(v,k){
        if(v.id==value.id){
            $scope.jsonArray3.push(v);
        }
    })
})



$q.all($scope.jsonArray3).then(function(data){
   console.log("data:",data);
})

You can also use map : 你也可以使用map

var requests = cardTitles.map(function(title) {
  var deferred = $q.defer();
  Trello.post('/path', {}, deferred.resolve, deferred.reject);
  return deferred;
});

$q.all(requests).then(function() {

});

And if the post method already returns a promise: 如果post方法已经返回一个promise:

var requests = cardTitles.map(function(title) {
  return $http.post('/path/' + title, {});
});

$q.all(requests).then(function() {

});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM