2011-11-05 102 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」。 –