如何在angular.js中处理多个异步任务?

时间:2013-12-03 09:26:47

标签: javascript mongodb angularjs asynchronous callback

使用沙盒应用程序学习angular.js我在代码中的几个地方遇到过以下模式。我发现自己不得不在循环中查询mongoDB。据我了解,每次调用都发生在自己的异步任务中。我怎么知道所有任务何时完成?

例如,我有一个状态的数组。我经常需要为每个状态将 someProperty 设置为 someNewValue 。一旦所有状态都已更新,我想调用 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();
    });
}

目前,我能想到的唯一方法是每次更新成功时调用 someFunction()。我知道必须有一个更聪明,更好的方法。

你的方法是什么?

1 个答案:

答案 0 :(得分:19)

承诺和$q.allref)是您的朋友。

更详细地说,您必须为每个调用做出承诺(如果调用本身没有返回),将它们推入数组并调用$q.all(promises).then(allFinished)。天真的情况,其中$update()没有返回承诺:

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

callUpdate()存在的原因是封装延迟对象处理并返回promise。