2011-11-05 104 views
31

可能重复:
Kill Ajax requests using JavaScript using jQuery使用Jquery .ajax取消正​​在进行的AJAX请求?

下面是简单的代码,我有工作:

$("#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); 
     } 
    }); 
} 

本质上讲,如果一个keyup事件是在函数obtainFriendlist返回之前解雇结果(并触发UIDisplayFriends(味精),我需要取消在飞行中的请求。我一直有的问题是,他们bui升起,然后突然重复触发函数UIDisplayFriends。

非常感谢您,并建议有利于太

回答

19

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

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

添加一些去抖动以减轻服务器负载可能很明智。以下仅在用户停止输入100ms后才会发送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); 
     } 
    }); 
} 
+1

我喜欢你对延迟所做的事情,这很好。但是,如果用户是一个缓慢的作家,那么请求堆积起来还是没有风险,每次击键都会触发一个新的ajax请求? –

+1

它仍然是一个风险,所以你会想要应用这两种策略,取消旧的查询和上述方法来减少服务器调用。第三个屏幕将验证输出是否仍然匹配请求。 –

+1

非常好。谢谢,这是非常丰富的 – TaylorMac

0

如何使用一个变量,说isLoading,您通过使用beforeSend(jqXHR,设置)选项阿贾克斯,然后使用设置为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; } 
    }); 
} 
+1

这岂不是相反的?如果用户在XHR返回之前键入“TEST”,则E,S和T的按键将被忽略,服务器响应将仅用于“T”。 –