2014-09-10 30 views
1

我有这个fiddle的例子,其中我连续三次调用服务函数(模拟$ http Request拦截器函数)返回一个promise,代码如下。我希望第二次和下一次调用要等到先前的结束,因为第二次和下一次调用取决于先前的响应。目前即时得到Angularjs Implemet异步任务队列

消息1:返回的值是6000,

消息2:返回的值是600

消息3:返回的值是30

,但我想

消息1:返回的值是10

消息2:返回的值是200

消息3:返回的值是6000

var myApp = angular.module('myApp', []); 

myApp.factory('interceptor',['$q','$timeout',function($q,$timeout){ 
    var _fact ={}; 
    var asynTimeout; 
    var _intvalue = 1; 
    var _asyncTask = function(time, value){ 
    var deferred = $q.defer(); 

    asynTimeout = $timeout(function(){ 
      _intvalue = _intvalue*value 
      deferred.resolve(_intvalue);},time) 


    return deferred.promise; 
}; 

    _fact.asyncTask = _asyncTask; 
    return _fact; 
}]); 

myApp.controller('AppCtrl',['$scope', 'interceptor',function ($scope,interceptor) { 

    interceptor.asyncTask(1500, 10).then(function(returnedval){ 
    $scope.message1 = "The value returned is " + returnedval;}); 

    interceptor.asyncTask(1000, 20).then(function(returnedval){ 
    $scope.message2 = "The value returned is " + returnedval;}); 

    interceptor.asyncTask(800, 30).then(function(returnedval){ 
    $scope.message3 = "The value returned is " + returnedval;}); 

}]) 

模板将是:

<div ng-controller="AppCtrl"> 
    <div>Message 1: {{message1}}</div> 
    <div>Message 2: {{message2}}</div> 
    <div>Message 3: {{message3}}</div> 
</div> 

通知,溶液应在工厂功能在控制器-nested调用来实现的是不是一个解决方案对于这种情况下,我想要的是在拦截器端如下的东西

myApp.factory('interceptor',['$q','$timeout',function($q,$timeout){ 
    ... 

    var _asyncTask = function(time, value){ 
    var deferred = $q.defer(); 

    ***IF ITS RUNNING A PREVIOUS CALL WAIT FINISHES AND THEN(function(){*** 
     asynTimeout = $timeout(function(){ 
      _intvalue = _intvalue*value 
      deferred.resolve(_intvalue);},time) 
    ***}** 
    return deferred.promise; 
    }; 

    ... 

    return _fact; 
}]); 

回答

1

试试这个。撇开前面的$timeout的承诺,并用它等待以前的操作完成。还简化了它一下,除去递延,并使用$timeout的承诺,而不是...

myApp.factory('interceptor', ['$q', '$timeout', function ($q, $timeout) { 
    var _fact = {}; 
    var _intvalue = 1; 
    var waitPromise = $q.when(true); 

    var _asyncTask = function (time, value) { 
     waitPromise = waitPromise.then(function() { 
      return $timeout(function() { 
       _intvalue = _intvalue * value; 
       return _intvalue; 
      }, time); 
     }); 
     return waitPromise; 
    }; 

    _fact.asyncTask = _asyncTask; 
    return _fact; 
}]); 

Fiddle

+0

完美,正是我一直在寻找 – user3281440 2014-09-10 17:14:42

0

是否显示消息1, 2,3重要吗?如果没有,可以嵌套asyncTask,请参阅 jsfiddle.net/1k6Lswab/8/

+0

正如我前面提到的,控制器端的嵌套异步任务调用不是此方案的解决方案。 – user3281440 2014-09-10 16:14:08

+0

啊,我错过了你发布的最后一部分:) – ABOS 2014-09-10 16:18:44

1

您可以创建在工厂承诺的队列。像这样:

myApp.factory('interceptor',['$q','$timeout',function($q,$timeout){ 
    var _fact ={}; 
    var asynTimeout; 
    var queue = $q.when(); 
    var _intvalue = 1; 
    var _asyncTask = function(time, value){ 
     queue = queue.then(
      function() { 
       var deferred = $q.defer(); 
       asynTimeout = $timeout(function(){ 
        _intvalue = _intvalue*value 
        deferred.resolve(_intvalue); 
       },time) 
       return deferred.promise; 
      } 
     ) 
     return queue; 
    }; 
    _fact.asyncTask = _asyncTask; 
    return _fact; 
}]);