2013-01-12 77 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) 
}