2013-01-12 194 views
4

我送一個AJAX請求到服務器上的用戶輸入到<input>元素,像這樣:發送的jQuery Ajax請求

$('#my-input').bind("input", function(event){ 
    // here's the ajax request 
}); 

讓我困擾的是,它在發送不必要的大量請求每個用戶的密碼,這意味着如果用戶輸入速度非常快,就會有很多不必要的請求。所以我認爲應該有一定的延遲/超時,等待一段時間(50毫秒?),以便用戶在發送ajax請求之前停止鍵入。那將解決一個問題。

但是,在發送另一個請求之前第一個Ajax請求尚未完成的情況呢? (輸入60毫秒/字符,而阿賈克斯請求需要300毫秒)。

解決此問題的最佳方法是什麼(基於想法和基於代碼的)?

+0

你想捕捉每一個擊鍵,或你想只捕獲結束消息(模糊)? – sgeddes

+0

@sgeddes:我不想每次捕捉,我都想要結束消息,但最後沒有模糊(用戶不必去掉區域)。 –

+0

只是捕捉輸入一個選項?或忽略退格 - 不知道這是否會實際幫助雖然 –

回答

3

您可以在下劃線庫中使用throttle函數。正如其文檔所述:

創建並返回傳遞函數的一個新的節制版本,即在重複調用時,每等待幾毫秒只能實際調用最多一次原始函數。對速度限制事件有用,速度限制事件的發生速度比您可以跟上的要快。

即使您不想引入新庫,您仍然可以從source code瞭解該功能的工作原理。事實上,throttle功能的簡單版本可能是:

function throttle(func, delay) { 
    var timeout = null; 
    return function() { 
     var that = this, args = arguments; 
     clearTimeout(timer); 
     timeout = setTimeout(function() { 
      func.apply(that, args); 
     }, delay); 
    }; 
} 

這個jQuery throttle-debounce plugin也很有幫助。尤其是,debounce功能根據其作者不是throttle功能似乎更適合你的需求:

去抖可以成爲速率限制,將觸發AJAX事件處理程序的執行是特別有用的請求

+0

我不認爲這是解決這個問題的最好方法。圖書館似乎對我來說是非常不必要的 –

+1

如果你使用JS密集型,這個庫是你的好朋友。無論如何,你可以從源代碼中獲取代碼片段。 –

+0

我同意你惠正。 –

1

你可以使用setTimeout函數。每隔一段時間,看文本是否沒有改變,如果沒有改變,則相應地進行處理。

setTimeout(function() { 
     // Do something after 1 second 
}, 1000); 
+0

是的,這解決了問題的第一部分,但不是覆蓋ajax請求。 –

+0

這可能是你必須解決服務器端的問題。在提交給數據庫之前排隊請求。那裏有幾個不同的實現。 – sgeddes

0

您可以在您的ajax請求中設置async:false,以便它僅在完成第一個ajax請求後才處理第二個ajax調用。

0

我會去@HuiZeng's answer,但以防萬一你想稍微修改版本。

步驟

  1. 聽使用的setTimeout,你可以清除到KEYDOWN。
  2. 火災時,檢查是否有在隊列前面的請求,如果有則中止並觸發一個新的

例子:

var inputTimer = 0, req; 

function onInput(e){ 
     clearTimeout(inputTImer); 
     inputTimer = setTimeout(function(){ 
      // You have access to e here 
      // Cancel any previous requests 
      req && req.abort(); 
      req = $.ajax({/*...Do your magic here :)*/}) 
     }, 100) 
}