问题
Is there a way to cancel a deferred callback queue in progress? I have an arbitrary amount of ajax calls. I'd like to stop further ajax requests when data of success returns specific marker:
this.oDeferred=$.Deferred();
this.oChain=this.oDeferred;
for(var i=0; i<this.aKey.length; i++) {
(function(iKey,self) {
self.oChain=self.oChain.then(function(){
return $.ajax({
url:self.aUrl[iKey],
type:'post',
data:{'ajax':true},
dataType:'json',
success:function(data) {
if(data.bCancel==true) {
//stop deferred object here!
}
}
});
})
}(this.aKey[i],this))
}
this.oDeferred.done(function() {
console.log('done')
});
this.oDeferred.resolve()
By the way - the function done() is fired autonomous after all ajax requests are made. How to execute a function after all ajax requests are done?
Thank you in advance!
回答1:
The answer is yes. Two approaches are possible.
.then()
The .then()
method returns a new promise, the state of which is determined by what is returned from the handler(s) passed to the method.
- by returning a value/object that is a non-promise, a new promise is passed down the method chain with the same resolved/rejected status as the original promise but resolved/rejected with the returned value/object.
- by returning a promise, that promise is passed down the method chain, with a status that is independent of the original promise.
Thus, Deferred/promise callback queue can be effectively canceled by returning from a .then()
handler a promise that is never resolved and never rejected. Such a promise can be made from the .then()
handler's done handler (first argument) or its fail handler (second argument). The same cannot be achieved with .done()
, .fail()
or .always()
methods, which return the original Deferred/promise without modification.
Throw an error
An uncaught error thrown from within a .then()
, .done()
, .fail()
, .always()
or .progress()
handler will kill a method chain by killing the event thread in which it is running.
An error can be thrown deliberately with eg throw('deliberate error')
.
Note
It should be noted that both approaches will only suppress chained method handlers (or the equivalent achieved by assignment).
With either approach, any asynchronous process that is already initiated at the point the suppressing return/error expression executes will continue and any corresponding done/fail/always/progress handler already in place may fire.
回答2:
Reading through the jQuery docs, there doesn't appear to be a built in method to do what you want. There is a plugin which may get you where you need to be called jQuery-timing. This thread may also be of relevance to you Canceling a Deferred Promise in jQuery.
来源:https://stackoverflow.com/questions/16335597/jquery-deferred-cancel-progress