4

我在用户输入<input>元素时向服务器发送 ajax 请求,如下所示:

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

困扰我的是,它在每个用户的键位上发送了不必要的许多请求,这意味着如果用户键入非常快,就会有许多不必要的请求。所以我认为应该有一定的延迟/超时,等待一定的时间(50 毫秒?)让用户在发送 ajax 请求之前停止输入。那将是解决一个问题。

但是在发送另一个请求之前第一个 ajax 请求还没有完成的情况呢?(键入 60 毫秒/字符,而 ajax 请求需要 300 毫秒)。

解决这个问题的最佳方法是什么(基于想法和代码)?

4

4 回答 4

3

您可以在下划线库中使用油门功能。正如其文档所述:

创建并返回传递函数的新的、受限制的版本,当重复调用时,每等待毫秒最多只会实际调用一次原始函数。对于发生得比您跟得上快的限速事件很有用。

即使你不想引入一个新的库,你仍然可以从它的源代码中了解这个函数是如何工作的。事实上,一个简单的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 插件也很有帮助。特别是,根据作者的说法,该debounce功能似乎比功能更适合您的需求:throttle

去抖动对于限制将触发 AJAX 请求的事件的处理程序执行的速率特别有用

于 2013-01-12T05:21:04.760 回答
1

您可以只使用 setTimeout 函数。每隔一段时间,看看文本是否没有改变,如果没有,然后进行相应的处理。

setTimeout(function() {
      // Do something after 1 second
}, 1000);
于 2013-01-12T05:26:28.440 回答
0

您可以在您的 ajax 请求中设置 async: false ,这样它只会在第一个 ajax 请求完成后处理第二个 ajax 调用。

于 2013-01-12T06:18:27.043 回答
0

我会选择@HuiZeng 的回答,但以防万一你想要一个稍微修改的版本。

脚步

  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)
 }
于 2013-01-12T08:07:50.990 回答