2010-08-04 186 views
6

我有一個特定的函數,我想運行一次,並且只在完成幾個AJAX請求之後。只有在多個AJAX請求完成後觸發函數

我目前的解決方案看起來有點像這樣:

function doWork() { 
    //This is the function to be run once after all the requests 
} 

//some tracking/counting variables 
var ajaxDoneCounter = 0; 
var numOfAjaxRequests = 5; 
var workDone = false; 

function doWorkTrigger() { 
    ajaxDoneCounter++; 
    if(!workDone && ajaxDoneCounter >= numOfAjaxRequests) { 
     workDone = true; 
     doWork(); 
    } 
} 

// ... 

//and a number of ajax requests (some hidden within functions, etc) 
//they look something like this: 
$.ajax({ 
    url: "http://www.example.com", 
    dataType: "json", 
    success: function(data) { 
     //load data in to variables, etc 
     doWorkTrigger(); 
    } 
}); 

一個在上面的明顯缺陷是任何AJAX調用不成功也不會增加ajaxDoneCountdoWork()可能永遠不會被調用。我可以在任何$.ajax的內部使用error回調來解決這個問題,這樣就不用擔心太多。

我想知道的是以上是否安全和/或良好的做法?
有沒有我錯過的技巧,或其他任何可能更好的工作?

+1

它是什麼,我會建議你從閱讀問題描述做。我不確定「我想不出任何更好的東西」是一個合適的「答案」,儘管如此只是評論而已。 ;-) – Chris 2010-08-04 11:58:17

回答

6

更新:由於jQuery 1.5,deferred objects[docs]提供了一個更乾淨的解決方案。 Have a look at an example here

var numOfAjaxRequests = 5; 

$(document).ajaxComplete(function() { 
    numOfAjaxRequests--; 
    if(!numOfAjaxRequests) { 
     doWork(); 

    } 
}); 

然後,你不必編輯每一個Ajax請求:


我會用.ajaxComplete(),每當一個Ajax調用完成(成功或錯誤)將被觸發。

你甚至可以使用.ajaxSend()得到通知開始Ajax請求,而不是硬編碼的(但我不知道這是否真的有效,也許你會遇到競爭條件):

var numOfAjaxRequests = 0; 

$(document).ajaxSend(function() { 
    numOfAjaxRequests++; 
}); 
+0

啊,很高興知道 - 但是如果我有兩組Ajax調用,每個觸發一個分隔函數(我不知道,我只是想知道)。這種方法是否允許我分開兩組,這樣兩個功能都不會堅持等待它完成的所有組? – DMA57361 2010-08-04 12:01:51

+0

@ DMA57361:查看文檔。XMLHttpRequest和Ajax調用的選項將被傳遞給回調函數。您可能能夠將這些電話與這些信息區分開來。在文檔中是一個例子,回調只有在Ajax調用是針對特定URL時纔會執行。 – 2010-08-04 12:06:10

+0

對我來說看起來很好,我認爲我會很好的閱讀那裏的文檔,並進一步調查這兩個文檔。謝謝。 – DMA57361 2010-08-04 12:31:30

0

我不對JavaScript內部知識不夠充分,但存在操作的危險:

ajaxDoneCounter++; 

不是原子的。如果是這樣,那麼這可能會受到競爭條件的影響。

+0

爲什麼downvote?如果++在JavaScript中是原子的,那就發表一條關於它的評論。發佈答案後我的快速研究似乎表明,ECMAScript不聲明如果++是原子或不是。 – 2010-08-05 00:11:30

+0

我想知道這個-1以及我發現[this](http://stackoverflow.com/questions/1663125/is-javascript-multithreaded)的問題,這似乎表明JavaScript只是作爲一個單線程,所以推測它會在他們完成時將ajax回調排隊 - 這意味着這個特定的問題是不相關的。不過,如果誰做了downvote的話,它會很有幫助,因爲它已經困擾了*告訴我們...... – DMA57361 2010-08-05 08:15:41

+0

是的,以及http://stackoverflow.com/questions/1663125/is-javascript-multithreaded/1663578#1663578表明它可能並不總是如此。 – 2010-08-06 04:02:24

1

我認爲你應該使用complete(XMLHttpRequest, textStatus) ajax事件而不是成功(data,textStatus,XMLHttpRequest)。

據jQuery的幫助:

complete(XMLHttpRequest, textStatus) 

的函數 請求完成(成功後 錯誤回調執行)時調用。 函數獲取兩個參數: 描述請求狀態的XMLHttpRequest對象和字符串 。 這是一個Ajax事件。

相關問題