假设我想创建一个包含至少2个Deferred对象的主延迟对象。如果至少有一个子延迟对象得到解析,则必须解析此主延迟对象。我怎么能用JQuery做到这一点?
我知道如果我做那样的事情
function resolveMaster(){
var requests = [];
requests.push(request1);
requests.push(request2);
return $.when.apply($, requests);
}
如果所有请求都得到解决,那么它将被解决。
这就是我想要做的。如果请求成功 AND 返回的数组不为空(!important),则应解决这些函数内的Ajax请求。
//request1 is different from request2
request1 : function() {
var dfd = new jQuery.Deferred();
$.ajax({
url : "someURL",
success : function(data) {
if (data && data.length > 0) {
//some code here
dfd.resolve(data); //this is important here
} else {
dfd.reject();
}
},
error : function() {
dfd.reject();
}
});
return dfd.promise();
}
//request2 is different from request1
request2 : function() {
var dfd = new jQuery.Deferred();
$.ajax({
url : "someURL",
success : function(data) {
if (data && data.length > 0) {
//some code here
dfd.resolve(data); //this is important here
} else {
dfd.reject();
}
},
error : function() {
dfd.reject();
}
});
return dfd.promise();
}
答案 0 :(得分:2)
这通常称为any
或some
,并未在jQuery中实现。
幸运的是,你可以自己轻松实现这一点。
function any(promises){
var d = $.Deferred(); // new promise
// on the first success - resolve it
for(var i = 0;i < promises.length; i++) promises[i].then(d.resolve);
// this is enough since a promise is immutable after it resolves and if we
// call it more than once it will keep the original value
return d.promise(); // return the promise we created
}
或简而言之:
function any(promises){
var d = $.Deferred();
for(var i = 0; i < promises.length; i++) promises[i].then(d.resolve);
return d.promise();
}
// then you can do
any([$.ajax("firstUrl"), $.ajax("secondUrl")]).then(function(response){
// response from whichever finished first.
});
另请注意,$ .ajax已经返回了一个承诺,因此您不需要延迟它 - 您只需return $.ajax
并获得与整个Deferred
/相同的结果success:
事
如果您还想拒绝所有承诺拒绝 - 您可以这样做:
function any(promises){
var d = $.Deferred();
var sem = promises.length;
for(var i = 0; i < promises.length; i++){
promises[i].fail(function(el){
sem--;
if(sem === 0) d.reject(el); // reject all, with last's error
}).then(d.resolve);
}
return d.promise();
}