2012-06-16 70 views
3

目前,我使用的setInterval運行調用PHP頁面,像這樣幾個AJAX功能 -替代的setInterval是等待函數來完成

var intervalOne = setInterval(ajaxfunction, 1500); 

能正常工作在測試服務器上有微小的響應時間。然而,偶爾在我的實時服務器上,會有一點滯後,間隔時間會在第一個完成之前再次出現,重複相同的調用並導致重複的數據出現。

有沒有辦法保持相同的間隔時間,但是如果第一個還沒有完成,是否有等待調用該函數?

另外,有什麼我可以放在AJAX調用的readystate部分,讓他們一旦完成後再次觸發自己?

編輯 - 我的Ajax調用一個實例:

function Send() { 
var name = document.getElementById('name').value; 
var message = document.getElementById('message').value; 

var xmlhttp = getXMLHttp(); 

xmlhttp.onreadystatechange = function() { 
    if(xmlhttp.readyState == 4) 
    { 
     document.getElementById('message').value = ""; 

     if(xmlhttp.responseText != "") { 
      var chat = document.getElementById('messagebox'); 
      chat.innerHTML = chat.innerHTML + '<div class=\"alert\">' + xmlhttp.responseText + '</div>'; 
      chat.scrollTop = 1000000000; 
     } 
    } 
} 

xmlhttp.open("POST","submit_message.php",true); 
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); 
xmlhttp.send("name=" + name + "&message=" + message); 

} 
+2

只需在函數結尾調用setTimeout? –

+0

顯示您的AJAX呼叫,以便我們提供更好的答案。 –

+0

@James我真的可以自己調用一個函數嗎? – Morgan

回答

6

最簡單的方法是通過在你的進程結束盲目重新應用setTimeout

function foo() { 
    // possibly long task 
    setTimeout(foo, 1500); 
} 
foo(); 

這將等待你的進程之間的1500毫秒。就像這樣:300ms的過程中,1500毫秒等待,2000點毫秒過程中,1500毫秒等待,400ms的過程中,1500毫秒稍候...

有點更接近於你想要什麼,你可以重新申請setTimeout開始你的過程。在這種情況下,你會得到:300ms進程,1200ms等待,2000ms進程,0ms等待,400ms進程,1100ms等待... setInterval發生的問題在這裏不會發生,因爲這隻會計劃下一個迭代,不是所有未來的。還要注意,由於JS是單線程的,所以事件不能像其他語言中那樣中斷自身。

function foo() { 
    setTimeout(foo, 1500); 
    // possibly long task 
} 
foo(); 

,是的,我想這是更受追捧,使其自動執行的,因爲你可以在一些答案看;但這只是美學,最終效果是一樣的。

+0

謝謝,那正是我需要的。我沒有意識到我可以設置參數來影響函數本身聲明中函數的迭代。 – Morgan

+0

當一個完成時,摩根總是做另一個Ajax請求,所以試試@ TomaszNurkiewicz的回答 – 2012-06-16 12:45:52

2

您可以創建setTimeout這樣沿着自我調用函數:

(function foo(){ 

// your code logic here 

setTimeout(foo, 5000); 

})(); 

這裏的區別是,它的工作類似到setInterval但與其不同,只有在your code logic here部分執行完畢後纔會執行下一個函數調用。

查看DEMO這裏。

3

您可以替換setInterval()setTimeout()每個Ajax響應不斷被重新安排:

function Send() { 
    //... 
    xmlhttp.onreadystatechange = function() { 
     if(xmlhttp.readyState == 4) { 
      setTimeout(Send, 1500); 
      //... 
     } 
    } 
} 

Send(); 

如果你並不需要精確到毫秒,這是好的(電話之間的時間將是1500毫秒+平均響應時間)。如果您需要每1500毫秒調用一次服務器,則可以從1500毫秒中減去響應時間。

+0

最好的答案,但它沒有在jquery下標記 – 2012-06-16 12:08:52

+0

這是一個有用的答案,但我不希望爲一個單一任務添加jQuery。 :) – Morgan

+0

@Somebodyisintrouble:[tag:jquery]僅用於強調這個想法,但是由於OP公佈了原始代碼,所以使用原始XMLHttpRequest代替。 –