2013-12-09 120 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