Angularjs实现异步任务队列

时间:2014-09-10 15:56:03

标签: angularjs angular-promise

我有这个fiddle示例,其中我连续三次调用服务函数(模拟$ http请求拦截器函数)返回一个promise,代码如下。我希望第二次和下一次调用等到上一次完成,因为第二次和下一次调用取决于之前的响应。目前我正在

消息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> 

注意,解决方案应该在工厂函数中实现 - 控制器的调用不是这种情况的解决方案 - 我想要的是拦截器端的跟随

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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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;
}]);

答案 2 :(得分:0)

显示消息1,2,3的顺序是否重要?如果没有,你可以嵌套asyncTask,参见       jsfiddle.net/1k6Lswab/8 /