如果至少有一个请求得到解决,则JQuery延迟解析

时间:2014-11-06 11:20:36

标签: jquery promise jquery-deferred

假设我想创建一个包含至少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();
}

1 个答案:

答案 0 :(得分:2)

这通常称为anysome,并未在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(); 
 }