我有这个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;
}]);
答案 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;
}]);
答案 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 /