【问题标题】:Cancel in-flight AJAX requests using Jquery .ajax? [duplicate]使用 Jquery .ajax 取消正在进行的 AJAX 请求? [复制]
【发布时间】:2011-12-22 20:36:41
【问题描述】:

可能重复:
Kill Ajax requests using JavaScript using jQuery

这是我正在使用的简单代码:

$("#friend_search").keyup(function() {

    if($(this).val().length > 0) {
        obtainFriendlist($(this).val());
    } else {
        obtainFriendlist("");
    }

});

function obtainFriendlist(strseg) {

    $.ajax({
       type: "GET",
       url: "getFriendlist.php",
       data: "search="+strseg,
       success: function(msg){
        UIDisplayFriends(msg);
       }
     });
}

本质上,如果在函数 acquireFriendlist 返回结果之前触发了 keyup 事件(并触发 UIDisplayFriends(msg),我需要取消正在进行的请求。我遇到的问题是它们建立起来,然后突然,函数 UIDisplayFriends 被反复触发。

非常感谢,建议也很有帮助

【问题讨论】:

    标签: php javascript jquery ajax


    【解决方案1】:

    $.ajax 的返回值是一个 XHR 对象,您可以对其调用操作。要中止该功能,您可以执行以下操作:

    var xhr = $.ajax(...)
    ...
    xhr.abort()
    

    添加一些去抖动以减轻服务器上的负载可能是明智之举。以下仅在用户停止输入 100 毫秒后才会发送 XHR 调用。

    var delay = 100,
        handle = null;
    
    $("#friend_search").keyup(function() {
        var that = this;
        clearTimeout(handle);
        handle = setTimeout(function() {
            if($(that).val().length > 0) {
                obtainFriendlist($(that).val());
            } else {
                obtainFriendlist("");
            }
        }, delay);
    });
    

    您真正应该做的第三件事是根据请求是否仍然有效来过滤 XHR 响应:

    var lastXHR, lastStrseg;
    
    function obtainFriendlist(strseg) {
        // Kill the last XHR request if it still exists.
        lastXHR && lastXHR.abort && lastXHR.abort();
    
        lastStrseg = strseg;
        lastXHR = $.ajax({
           type: "GET",
           url: "getFriendlist.php",
           data: "search="+strseg,
           success: function(msg){
    
            // Only display friends if the search is the last search.
            if(lastStrseg == strseg) 
              UIDisplayFriends(msg);
           }
         });
    }
    

    【讨论】:

    • 我喜欢你对延迟的处理,这很好。但是,如果用户是一个慢写者,是否仍然存在请求堆积的风险,每次击键都会触发一个新的 ajax 请求?
    • 这仍然存在风险,因此您需要同时应用这两种策略,取消旧查询和上述减少服务器调用的方法。第三个屏幕将验证输出是否仍然与请求匹配。
    • 优秀。谢谢,这非常有用
    【解决方案2】:

    如何使用变量,比如 isLoading,通过使用 .ajax 的 beforeSend(jqXHR, settings) 选项设置为 true,然后使用完整设置将变量设置回 false。然后在触发另一个 ajax 调用之前验证该变量?

    var isLoading = false;
    $("#friend_search").keyup(function() {
    
        if (!isLoading) {
           if($(this).val().length > 0) {
               obtainFriendlist($(this).val());
           } else {
               obtainFriendlist("");
           }
        }
    
    });
    
    function obtainFriendlist(strseg) {
    
        $.ajax({
           type: "GET",
           url: "getFriendlist.php",
           beforeSend: function () { isLoading = true; },
           data: "search="+strseg,
           success: function(msg){
            UIDisplayFriends(msg);
           },
           complete: function() { isLoading = false; }
         });
    }
    

    【讨论】:

    • 这不是相反吗?如果用户在 XHR 返回之前键入“TEST”,则 E、S 和 T 的按键将被忽略,服务器响应将仅为“T”。
    猜你喜欢
    • 1970-01-01
    • 2014-06-15
    • 2019-04-07
    • 2013-08-26
    • 2012-07-29
    • 2012-04-22
    • 2011-05-31
    相关资源
    最近更新 更多