我試圖爲我的網站用戶實現一個搜索欄像Facebook一樣。輸入名稱時,會顯示一些結果。 爲了避免爲每個按鈕發送請求,我設置了超時。這個想法是:如果我要輸入jack
搜索j
,ja
,jac
,jack
沒有任何意義,但最好等待用戶在發送任何請求之前完成打字。 一旦請求被髮送並完成,一個名爲mydiv
的div就會被提交結果(請求響應)。如果經過一段時間足夠長的時間,我又輸入另一封信,發送另一個請求,並且mydiv
中充滿了新的結果。第二個jQuery.post請求在第一個之前完成。如何避免這種情況?
這個想法來自。 這是我簡化的實現。
var thread = null;
$('#search-user').keyup(function() {
clearTimeout(thread);
name = $('this').val(); //i get the name just typed
thread = setTimeout(function(){
get_data_with_ajax_and_put_it_in_mydiv(name);
}, 200);
});
function get_data_with_ajax_and_put_it_in_mydiv(name){
$.post()....
/*Do some stuff*/
}
正如你可以看到,一個約200ms超時後功能get_data_with_ajax_and_put_it_in_mydiv();
被調用。此功能在輸入新數據之前清空mydiv
。它幾乎總是有效,但有時會出現一個奇怪的錯誤。
我打算通過提供一個真實的例子來解釋我認爲問題出在哪裏。讓我們假設get_data_with_ajax_and_put_it_in_mydiv()
需要從50ms到1000ms完成,具體取決於各種因素(網絡速度,擁塞等)。
- 在
t=0
我輸入jac
,我停止輸入。 - 在
t=200
超時到期並且get_data_with_ajax_and_put_it_in_mydiv()
運行。在這種情況下,需要1000ms運行 - 在
t=210
,因爲我是一個緩慢的作家,我輸入k
的字母jack
。mydiv
是空的,因爲 第一個請求尚未完成。 - 在
t=410
發送k
epires的超時和第二個請求 。這一次,該功能需要100ms才能運行。 - 在
t=510
第二個請求完成,我得到jack
的結果。 - 在
t=1200
第一個請求完成,我得到jac
的結果。
錯誤
正如你可以看到由於通過Ajax請求elaped時間impredictability我得到一個錯誤的結果。 mydiv
填充了jac
結果而不是jack
。
SOLUTION
說來我首先想到的解決方案是:每次我打電話get_data_with_ajax_and_put_it_in_mydiv()
時間我必須阻止任何先前的請求仍在運行。我怎樣才能做到這一點?如果不可能,我該如何解決這個錯誤?
中止以前的請求聽起來是個好主意。以下是如何中止Ajax請求:http://stackoverflow.com/a/446626/678801 –
快速而骯髒的解決方案是將搜索字符串包含在返回的結果中,並將其與您發送的最後一個搜索字符串進行比較。如果不一樣,只是忽略結果。 –
嘗試向請求發送時間戳並返回相同的時間戳。您將此時間戳存儲在全局變量中並更新每個請求。當請求完成時,在更新div內容之前,檢查時間戳是否與請求相同。您將始終有div上的最後一個請求結果。 – DontVoteMeDown