2013-12-09 122 views
8

多个并行的承诺,我要排队使用jQuery的递延/承诺实现多个异步Ajax请求:等待完成后使用jQuery

function doSomething() { 
    console.log('doSomething')}; 

function makeMultiAjaxRequests1() { 
    console.log('makeMultiAjaxRequests1')}; 

function makeMultiAjaxRequests2() { 
    console.log('makeMultiAjaxRequests2')}; 

var step1 = function() { 
    var promise = new $.Deferred().promise(); 
    makeMultiAjaxRequests1(); 
    return promise; } 

var step2 = function() { 
    var promise = new $.Deferred().promise(); 
    makeMultiAjaxRequests2(); 
    return promise; } 

step1() 
    .then(step2()) 
    .done(doSomething()); 

$.when(step1(), 
     step2()) 
    .done(function() { 
    doSomething(); 
}); 

这里是fiddle link。所以我的问题是:

在step1和step2并行执行的模式中,代码没有到达最后一个处理函数。为什么?

+0

你在哪里其实解决的承诺?如果不触发处理程序,则不会调用回调函数... – Bergi

+0

“step1()”和“step2()”中的延迟永远不会被解析。 –

+0

雅这是真的,但在前面的顺序示例中情况如何?承诺未解决,代码完成。 – crishushu

回答

0

它达到你done功能,如果你给它,它实际上可以达到(在的jsfiddle的情况下的URL,这将是说/echo/html/http://jsfiddle.net/LnaPt/2/

基本上,你只需要做到这一点:

var promise = $.ajax({ 
    type: "GET", 
    url: "/echo/html/", //<-- instead of google  
}).promise(); 
6

您需要解决的第一步和第二步的deferred OBJ

试试这个

function doSomething() { 
    console.log('doSomething')}; 

function makeMultiAjaxRequests1(deferred) { 
    console.log('makeMultiAjaxRequests1') 
    deferred.resolve()}; 

function makeMultiAjaxRequests2(deferred) { 
    console.log('makeMultiAjaxRequests2') 
    deferred.resolve()}; 

var step1 = function() { 
    var deferred = new $.Deferred(); 
    makeMultiAjaxRequests1(deferred); 
    return deferred; } 

var step2 = function() { 
    var deferred = new $.Deferred(); 
    makeMultiAjaxRequests2(deferred); 
    return deferred; } 

step1().then(step2).done(doSomething); 

$.when(step1(), step2()).done(function() { 
    doSomething(); 
}); 
+1

谢谢。你的建议有一个问题:为什么不在步骤中返回deferred.promise()。如果我们回复承诺,差异在哪里? – crishushu

+0

@crishushu推迟并承诺两者都有,做完方法。但承诺没有解决方法。 – Daiwei

+0

我的问题是指顺序案例的行为(step1()。then(step2).done(doSomething);)。如果我们返回延迟对象或者如果我们返回它的承诺,那么这没有区别;都会执行doSomething() – crishushu

4

@戴伟给出了一个很好的答案。

sergio-fry提到的一个共同的要点是https://gist.github.com/sergio-fry/3917217

你应该希望有一个更加动态的方法,你不知道你是事先有多少争论并行运行,这里是JQuery的一个很好的例子扩展(1.10+):

$.whenAll = function (deferreds) { 
    function isPromise(fn) { 
     return fn && typeof fn.then === 'function' && 
      String($.Deferred().then) === String(fn.then); 
    } 
    var d = $.Deferred(), 
     keys = Object.keys(deferreds), 
     args = keys.map(function (k) { 
      return $.Deferred(function (d) { 
       var fn = deferreds[k]; 

       (isPromise(fn) ? fn : $.Deferred(fn)) 
        .done(d.resolve) 
        .fail(function (err) { d.reject(err, k); }) 
       ; 
      }); 
     }); 

    $.when.apply(this, args) 
     .done(function() { 
      var resObj = {}, 
       resArgs = Array.prototype.slice.call(arguments); 
      resArgs.forEach(function (v, i) { resObj[keys[i]] = v; }); 
      d.resolve(resObj); 
     }) 
     .fail(d.reject); 

    return d; 
}; 

见代码动作与动态活生生的例子:

http://jsbin.com/nuxuciwabu/edit?js,console