AngularJS依次执行承诺

时间:2014-05-22 09:49:28

标签: javascript angularjs promise

我需要能够依次执行一系列异步事件,但每个事件的执行取决于最后一个事件的结果。反正有动态实现吗?请考虑以下代码作为我想要实现的目标的一个示例。

$scope.queries = [
    {
        id: 1,
        action: function(){
             var deferred = $q.defer();
             Service.something($.param(someData)).$promise.then(function(response){
                  deferred.resolve(response);
             }, function(error){
                  deferred.reject(error);
             });
             return deferred.promise;
        }
    },{
        id: 2,
        action: function(){
             var deferred = $q.defer();
             Service.something($.param(someData)).$promise.then(function(response){
                  deferred.resolve(response);
             }, function(error){
                  deferred.reject(error);
             });
             return deferred.promise;
        }
    },{
        id: 3,
        action: function(){
             var deferred = $q.defer();
             Service.something($.param(someData)).$promise.then(function(response){
                  deferred.resolve(response);
             }, function(error){
                  deferred.reject(error);
             });
             return deferred.promise;
        }
    },
];
$scope.stop = false;

angular.forEach($scope.queries, function(query) {
    if ($scope.stop === false) {
         query.action().then(function(result){
             //Everything is fine so we can continue to the next request
         }, function(error) {
            //This request produced an error so we need to stop
            $scope.stop = true;
            //Display error here
         });
    }
});

主要问题是如何让forEach等到每个动作的结果继续下一个动作之前?

任何帮助理解这一点并找到解决方案都会很棒。我能想到的唯一解决方案是使用链接的.then()手动链接这三个请求。

谢谢。

1 个答案:

答案 0 :(得分:2)

通常当我想按顺序运行时,我使用for或foreach循环,promises没有什么不同,并且不需要魔法,你只需要用.then指定延续

var promise = $q.when();

angular.forEach($scope.queries, function(query) {
    promise = promise.then(function(){ 
        // no need for scope.stop, a rejection will act like a throw and it'll
        // stop executing code
        return query.action();
    });
});

如果你想知道他们什么时候完成,你可以这样做:

promise.then(function(){
    alert("All actions done!");
});

注意,您的服务代码包含deferred anti pattern,您可以转换如下代码:

var deferred = $q.defer();
Service.something($.param(someData)).$promise.then(function(response){
    deferred.resolve(response);
}, function(error){
    deferred.reject(error);
});
return deferred.promise;

简单地做:

return Service.something($.param(someData)).$promise;