2012-09-05 83 views
16

我有一種情況,我的ajax調用必須以特定順序執行。我在其他情況下使用了jQuery Deferred對象,但似乎無法找到使其適當運行的方法。帶嵌套AJAX調用的jQuery延遲對象

我有一個函數在其生命週期中執行多個ajax請求。一些請求將在其他請求的成功回調期間執行。

我的問題:有沒有辦法將所有嵌套的延緩對象返回到原來的$.when調用?

一個簡單的例子是:

function nestedAjax() { 
    $.get("/", function(){ 
     console.log("First ajax done."); 
     $.get("/", function(){ 
      console.log("Second ajax done."); 
     }); 
    }); 
}; 

我想有nestedAjax功能使用$.when()$.done()像這樣:

$.when(nestedAjax()).done(function(){ 
    console.log("Complete"); 
});​ 

與控制檯輸出閱讀:

> First ajax done. 
> Second ajax done. 
> Complete. 

I可以返回第一個get來達到這個目的:

> First ajax done. 
> Complete. 
> Second ajax done. 

但是顯然這不是我所要求的。任何幫助,將不勝感激。

+0

如果它們必須按順序發生,爲什麼不首先執行同步請求?不要試圖在一個圓孔中安裝一個方形釘。 –

+0

你說得對。感謝喚醒電話。我設法重新排列並實現了我所需的功能。我仍然感興趣但是如果有一種方法可以從嵌套的ajax調用中收集延遲對象以進行評估,所以我的問題依然存在。 – Aesthete

+0

這很公平。 :)我可能沒有在這裏基地 - 這是很晚,我一直在工作 - 但也許在每個AJAX調用的回調函數,你可以添加對象到一個數組?你可以通過鏈傳遞數組作爲參數或將其留在全局空間中。 –

回答

14

其實很簡單。儘管所有的AJAX調用都是Deferred對象,但我仍然使用其中一個作爲方法本身。

function nestedAjax() { 
    var dfd = $.Deferred(); 
    $.get("/echo/json/", function(){ 
     console.log("First ajax done."); 
     $.get("/echo/json/", function(){ 
      console.log("Second ajax done."); 
      dfd.resolve(); 
     }); 
    }); 

    return dfd.promise(); 
}; 
+0

謝謝,我一直在更頻繁地使用它們,我現在看到爲什麼我無法完成我正在嘗試做的事情。謝謝您的幫助。當然是 – Aesthete

+0

!!我一直在反駁延遲幾個小時,只是沒有建立聯繫。謝謝博士! – Doga

+0

-1不處理錯誤。檢查@ dmnd的答案。 – Bergi

1

無法添加評論爲某些原因的上述答案。

所以我在這裏添加我的評論。只有ajax調用速度快並返回dfd.promise()之前,上述答案纔有效。

我有同樣的問題。正如你所看到的。返回的延遲對象表明它處於「掛起」狀態: http://jsfiddle.net/BtEKa/

+0

是的,你是絕對正確的。這是我得出的結論,在我的情況下,我有多個AJAX請求執行相同的功能。解決我的問題的最接近的辦法是使用'.ajaxComplete()',儘管我重新設計了我的方法並使其工作乾淨。 – Aesthete

+0

但請注意,如果你把它留在那。事件最終會在對象解決/拒絕後觸發。這是我的問題。我的對象返回了一個「掛起」狀態()...幾秒鐘後它改變了,我的事件開始發作。 – Juw

+0

在Python中,有能力從控制結構「產生」結果。這似乎是我需要的,在多個Ajax調用可能產生結果的情況下,在接收到所有結果後,可以解析「主」延遲對象。很明顯,與語言作鬥爭從中獲得某些行爲通常表明重新設計方法是必要的。 – Aesthete

6

實際上您並不需要額外的延遲對象。你可以做你用then()鏈接想要的東西:

function nestedAjax() { 
    return $.get("/echo/json/").then(function(result1){ 
     console.log("First ajax done."); 
     if (result1) { 
      return result1; 
     } else { 
      return $.get("/echo/json/").then(function(nestedResult){ 
       console.log("Second ajax done."); 
       return nestedResult; 
      }); 
     } 
    }); 
}; 

我增加了一些邏輯,因爲我認爲這可能是你同步執行此的原因。之後,您可以使用$.when中的結果,如下所示:

$.when(nestedAjax(), $.get("/something/else")).then(function(nested, other) { 
    console.log("Complete.", nested, other); 
}); 
+0

我在這裏沒有得到if/else。這會阻止第二個電話被髮出嗎?請解釋一下。 – Cymbals

+1

是的,第二個Ajax調用只會在第一個調用的結果是truthy時纔會發出。 – dmnd

+1

@dmnd:我想你的意思是「如果第一個的結果是虛假的。」 –