【问题标题】:How to avoid overhead of continuous ajax request on keyup event?如何避免在 keyup 事件上连续 ajax 请求的开销?
【发布时间】:2015-01-31 15:37:11
【问题描述】:

例如在搜索表单中,当用户输入一些文本时,AJAX 请求应该在每个 keyup 事件上发送,搜索键作为查询字符串。搜索键将是输入框中的值。

如果用户输入“ABCD”,在这种情况下,前 3 个 AJAX 请求应该被杀死/取消,因为在第 4 个 AJAX 请求中,searchkey 将是“ABCD”

$(document).ready(function(){
    $("#searchInput").keyup(function(){
        ajaxSearch( $("#searchInput").val() );
    });
});

在 keyup 事件中,我正在调用“ajaxSearch()”函数。

function ajaxSearch(searchKey) {
    $.ajax({
        type: "get",
        url: "http://example.com/ajaxRequestHandler/",
        data: "action=search&searchkey=" + searchKey
    }).done(function() {
        /* process response */
    });
}

【问题讨论】:

    标签: javascript jquery performance optimization


    【解决方案1】:
    var request;
    function ajaxSearch(searchKey) {
        /* if request is in-process, kill it */
        if(request) {
            request.abort();
        };
    
        request = $.ajax({
            type: "get",
            url: "http://example.com/ajaxRequestHandler/",
            data: "action=search&searchkey=" + searchKey
        }).done(function() {
            /* process response */
    
            /* response received, reset variable */
            request = null;
        });
    }
    

    【讨论】:

      【解决方案2】:

      避免多个ajax请求;我们可以参考并实现David Walsh's Blog post. 中提到的 debounce 函数,它对 Underscore.js 中的 debounce 函数实现有一些深刻的见解。 Debounce 功能只会在每分之一秒内触发一次,而不是在触发时触发。它肯定有助于限制连续的网络请求。

      // Returns a function, that, as long as it continues to be invoked, will not
      // be triggered. The function will be called after it stops being called for
      // N milliseconds. If `immediate` is passed, trigger the function on the
      // leading edge, instead of the trailing.
      function debounce(func, wait, immediate) {
          var timeout;
          return function() {
              var context = this, args = arguments;
              var later = function() {
                  timeout = null;
                  if (!immediate) func.apply(context, args);
              };
              var callNow = immediate && !timeout;
              clearTimeout(timeout);
              timeout = setTimeout(later, wait);
              if (callNow) func.apply(context, args);
          };
      };
      
      var ajaxSearch = debounce(function(searchKey) {
       //send an AJAX network request.
          $.ajax({
              type: "get",
              url: "http://example.com/ajaxRequestHandler/",
              data: "action=search&searchkey=" + searchKey
          }).done(function() {
              /* process response */
          });
       //250 indicates the minimum time interval between the series of events being fired
      }, 250);
      
      $("#searchInput").keyup(function(){
          ajaxSearch($("#searchInput").val());
      });
      

      【讨论】:

        【解决方案3】:

        当用户输入“ABCD”时,Atul Bhosale 的回答仍然有四个请求。只是打字速度和服务器响应时间的问题。

        最好使用超时。在这种情况下,如果用户“完成/超时”键入以下内容,则仅发送请求:

        $("#searchInput").keyup(function(){ 
            var value = $(this).val();
            setTimeout( function() { ajaxSearch(value) }, 300 );
        });
        

        只是玩弄超时。对我来说 300 毫秒就可以了...

        【讨论】:

        • 这可行,但考虑到如果服务器需要 5 秒来返回数据,在这 5 秒内,您可以根据 keyup 延迟处理 5000/300 个请求,这会导致各种问题如果处理不当。因此,当另一个 keyup 事件被触发时,您需要一种中止先前请求的方法。
        猜你喜欢
        • 1970-01-01
        • 2014-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-17
        • 1970-01-01
        • 2021-07-21
        相关资源
        最近更新 更多