最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to handle multiple async tasks in angular.js? - Stack Overflow

programmeradmin3浏览0评论

Working on a sandbox app to learn angular.js I have encountered the following pattern in several places in my code. I find myself having to query the mongoDB in a loop. As I understand it, each call happens in its own async task. How do I know when all the tasks are completed?

For instance, I have an array of states. Often I need to set someProperty to someNewValue for each of the states. Once all the states have been updated I would like to call someFunction().

for (var i = 0; i < $scope.states.length; i++) {
    $scope.states[i].someProperty = someNewValue;
    $scope.states[i].$update({stateId: $scope.states[i].id}, function() {
        someFunction();
    });
}

For now, the only way I can think of doing this is to call someFunction() every time each update succeeds. I know there must be a smarter and better way of doing this.

What would you be your approach?

Working on a sandbox app to learn angular.js I have encountered the following pattern in several places in my code. I find myself having to query the mongoDB in a loop. As I understand it, each call happens in its own async task. How do I know when all the tasks are completed?

For instance, I have an array of states. Often I need to set someProperty to someNewValue for each of the states. Once all the states have been updated I would like to call someFunction().

for (var i = 0; i < $scope.states.length; i++) {
    $scope.states[i].someProperty = someNewValue;
    $scope.states[i].$update({stateId: $scope.states[i].id}, function() {
        someFunction();
    });
}

For now, the only way I can think of doing this is to call someFunction() every time each update succeeds. I know there must be a smarter and better way of doing this.

What would you be your approach?

Share Improve this question asked Dec 3, 2013 at 9:26 Francesco GallarottiFrancesco Gallarotti 1,2271 gold badge16 silver badges40 bronze badges 1
  • 1 I answered a similar question earlier stackoverflow.com/questions/20144132/… – Chandermani Commented Dec 3, 2013 at 10:29
Add a comment  | 

1 Answer 1

Reset to default 20

Promises and $q.all (ref) are your friends.

In more detail, you will have to make a promise for each call (if the call itself does not return one), push them in an array and call $q.all(promises).then(allFinished). Naive case, where $update() does not return a promise:

function callUpdate(x, promises) {
    var d = $q.defer();
    x.$update({stateId: $scope.states[i].id}, function() {
        someFunction();
        d.resolve(); // it may be appropriate to call resolve() before someFunction() depending on your case
    });
    promises.push(d.promise);
}

...

var promises = [];
for (var i = 0; i < $scope.states.length; i++) {
    $scope.states[i].someProperty = someNewValue;
    callUpdate($scope.states[i], promises);
}

$q.all(promises).then(function() {
    // called when all promises have been resolved successully
});

The reason for the existence of callUpdate() is to encapsulate the deferred object handling and return the promise.

发布评论

评论列表(0)

  1. 暂无评论