问题
Let say I chained the $.Deferred
like this.
$.each(data, function(k, v) {
promise.then(function() {
return $.post(...);
}).then(function(data) {
if(data)... // here is the conditions
return $.post(...);
}).then(function(data) {
if(data)... // here is another condition
return $.post(...);
})
});
promise.done(function() {
console.log("All Done!");
});
Am I doing it right? how do I prevent the next chain to execute if the condition return false, and where do I do this:
if(data){
console.log('Success');
}
Can that code be in between those .then
s?
回答1:
Joey, whether or not you are doing it right depends on the detail of what you are trying to achieve.
If you are trying to build one long .then()
chain with a terminal .done()
, where each .then()
's 'done' handler either :
- calls an asynchronous process, or
- transparently passes data on to the next
.then()
in the chain
then, the code should be of the following form :
var promise = ...;//An expression that returns a resolved or resolvable promise, to get the chain started.
$.each(data, function(k, v) {
promise = promise.then(function() {//The `.then()` chain is built by assignment
if(data...) { return $.post(...); }
else { return data; }//Transparent pass-through of `data`
}).then(function(data) {
if(data...) { return $.post(...); }
else { return data; }//Transparent pass-through of `data`
});
});
promise.done(function() {
console.log("All Done!");
}).fail(function(jqXHR) {
console.log("Incomplete - an ajax call failed");
});
If, however, you are trying to do the same but where each .then()
's 'done' handler either :
- calls an asynchronous process, or
- interrupts the
.then()
chain
then, the code should be of the following form :
var promise = ...;//An expression that returns a resolved or resolvable promise, to get the chain started.
$.each(data, function(k, v) {
promise = promise.then(function(data) {
if(data...) { return $.post(...); }
else { return $.Deferred().reject(data).promise(); }//Force the chain to be interrupted
}).then(function(data) {
if(data...) { return $.post(...); }
else { return $.Deferred().reject(data).promise(); }//Force the chain to be interrupted
});
});
promise.done(function() {
console.log("All Done!");
}).fail(function(obj) {//Note: `obj` may be a data object or an jqXHR object depending on what caused rejection.
console.log("Incomplete - an ajax call failed or returned data determined that the then() chain should be interrupted");
});
回答2:
jQuery's then returns a new promise, which is monitored by the following chained then
. Whatever is returned from the previous then
is passed as the first argument of the next then
.
promise.then(function() {
return $.post(...);
}).then(function(data) {
//we return false or some indicator that next shouldn't run
if(!data) return false;
//else we return something
else return $.post(...);
}).then(function(data) {
//here we receive false, we return early, preventing further code from executing
if(!data) return false;
//otherwise, the following code runs
return $.post(...);
})
来源:https://stackoverflow.com/questions/16351050/conditionals-on-a-chained-deferred-in-jquery