2011-04-26 216 views
9

想象一下,我們想爲「富」和「酒吧」的併發請求後做什麼都成功完成,或報告錯誤情況下,如果一方或雙方的失敗:jQuery何時/然後/失敗併發ajax請求:哪個請求失敗?

$.when($.getJSON('foo'), $.getJSON('bar')) 
    .then(function(foo, bar) { 
    console.log('I fire if BOTH requests are successful!'); 
    }) 
    .fail(function() { 
    console.log('I fire if one or more requests failed.'); 
    }); 

如何確定如果1)'foo'的請求失敗,或2)'bar'的請求失敗,或3)兩者都失敗?

+0

您是否嘗試過只是做一次一個? – locrizak 2011-04-26 18:48:48

+0

@locrizak - 設想一個同時請求「foo」和「bar」的應用程序,但需要在處理它們之前成功返回。 – Javier 2011-04-26 18:55:30

+0

爲什麼不讓foo和bar根據成功或失敗返回true或false,調用這兩個函數並將它們的返回值保存在單獨的變量中?這樣你可以要求兩者都是真實的,如果不是,檢查兩者中哪一個是錯誤的。 – eagerMoose 2011-04-26 19:03:34

回答

10

只需添加一個失敗的調用是從$.getJSON返回各自承諾:

function make_error_handler(msg) { 
    return function() { console.log(msg); }; 
} 

$.when($.getJSON('foo').fail(make_error_handler("foo failed")) 
      , $.getJSON('bar').fail(make_error_handler("bar failed"))) 
    .then(function(foo, bar) { 
    console.log('I fire if BOTH requests are successful!'); 
    }) 
    .fail(function() { 
    console.log('I fire if one or more requests failed.'); 
    }); 

如果您需要更細粒度的控制,你可以重載$.getJSON附加信息返回給失敗的功能 - 見jQuery的文檔在deferred.rejectWith

0

你可以稱之爲.isResolved()檢查請求是否確實真正完成,但.when()的問題是,它會盡快要麼請求失敗失敗,這樣你就可以」 t可靠地告訴其他請求是否可能即將失敗。

我相信the answer I just postedsimilar question將解決(沒有雙關語意)這個要求,通過爲每個AJAX查詢,它可以讓你等到你知道,這兩個AJAX的實際結果調用中創建一個額外的$.Deferred

1

the documentation on jQuery.when

在其中Deferreds之一被拒絕多重Deferreds情況下,jQuery.when立即觸發其主延遲的failCallbacks。請注意,在這一點上,某些延期付款可能仍未解決。如果您需要爲這種情況執行額外的處理,例如取消任何未完成的ajax請求,則可以將引用保留在關閉中的基礎jqXHR對象中,並在failCallback中檢查/取消它們。

換句話說,你應該保留對每個請求的引用,並且自己手動檢查它,如果你需要的話。

難點在於,當調用失敗回調時,任何數量的延期的可以仍然是未完成的,因此在那個狀態他們既沒有失敗也沒有成功。

我希望文檔解釋一點,以確切地說,在這種情況下傳遞給失敗處理程序的內容。從源代碼,雖然來看,似乎是由故障處理收到的參數取決於其遞延失敗第一:

args[ i ].promise().then(resolveFunc(i), deferred.reject); 

我對jQuery的內部專家,但我認爲這只是讓每個遞延年代使用任何通常會傳遞給其處理程序的參數來調用「主」Deferred的reject方法。不理想,如果你問我......但是我可能會誤解這一點。

我不知道他們的意思這雖然:

args[ i ].promise().then(resolveFunc(i), func() { deferred.reject(args); });