2011-04-15 107 views
2

我使用setInterval,有時它發生「太快」。它下面的樣子:jQuery中的setInterval發生得太快

setInterval(function() { 
    //here comes ajax functions and so on. 
}, 1000); 

有時會發生的setInterval比所有這些AJAX功能,速度更快,它給了我兩個消息,而不是一個。這是什麼解決方案?

+1

也許你不應該使用的setInterval可言。您可能想要觸發這些呼叫,然後使用setTimeout在呼叫回來後再次安排呼叫。 – mahemoff 2011-04-15 21:09:59

回答

10

很難說出你遇到的問題,這個問題有點不清楚。

setInterval對於某些事情很有用,但不適用於任何需要混合其他異步內容的任何事情。相反,使用「重新安排setTimeout」成語:

setTimeout(doSomething, 1000); 
function doSomething() { 
    $.ajax("your_url", { 
     success: function() { 
      // Do something here 

      // Do something else here 
     }, 
     complete: function() { 
      // Previous run complete, schedule the next run 
      setTimeout(doSomething, 1000); 
     } 
    }); 
} 

...因爲,畢竟,你ajax通話可能需要超過一秒鐘來完成。

如果這不是你所遇到的問題,我的猜測是你的代碼看起來是這樣的:

setInterval(function() { 
    $.ajax("your_url", { 
     success: function() { 
      // Do something here 
     } 
    }); 

    // Do something else here 
}, 1000); 

...你想知道爲什麼「人在這裏做什麼」代碼運行在「在這裏做某事」代碼之前。如果是這樣,原因是默認情況下,ajax調用是異步。你的電話$.ajax開始的呼叫,但這就是全部;那麼在成功(或錯誤)回調發生之前,所有其他代碼都會運行。

的修復,當然,是在依賴於成功的回調頂級不做任何其他

setInterval(function() { 
    $.ajax("your_url", { 
     success: function() { 
      // Do something here 

      // Do something else here 
     } 
    }); 

}, 1000); 
1

最好不要使用setInterval,而是每次都設置一個新的setTimeout。例如:

setTimeout(function ajaxStuff() { 
    // here comes ajax functions and so on. 

    setTimeout(ajaxStuff, 1000); 
}, 1000); 

當然,如果內部的函數是異步的,因爲AJAX請求通常是,在setTimeout呼叫仍將會來得太早。您需要編寫一些在請求完成時調用setTimeout的代碼。 $.when可以幫助您與此,因爲$.ajax和其他的jQuery AJAX方法來實現$.Deferred

setTimeout(function ajaxStuff() { 
    $.when(
     $.ajax({ 
      url: 'ajax1.htm' 
     }), 
     $.ajax({ 
      url: 'ajax2.htm' 
     }), 
     $.ajax({ 
      url: 'ajax3.htm' 
     }) 
    ).done(function() { 
     setTimeout(ajaxStuff, 1000); 
    }); 
}, 1000); 
+0

這是否只是排隊XHR請求,然後立即設置下一個超時,這可能會導致相同的行爲? – 2011-04-15 21:07:43

+0

@Jason是的。爲了解決這個問題,我編輯了一半。 – lonesomeday 2011-04-15 21:08:54

1

設置一個標誌,指示阿賈克斯取的過程中。當所有ajax提取完成後,清除標誌。在setInterval函數的頂部,如果標誌被設置,立即返回。

1

我覺得這裏的問題是由於範圍。儘管該方法已成功觸發。

類似的問題我已經能夠使用該修復:

setTimeout(function(){ 
    load1(); 
}, 5000); 

function load1() { 
    console.log('loaddd1..'); 
    setTimeout(load2(), 4000); 
} 

function load2() { 
    setTimeout(function(){ 
    console.log('end load2'); 
}, 4000);