Pregunta ¿Cancelar las solicitudes AJAX en vuelo utilizando Jquery .ajax? [duplicar]


Posible duplicado:
Elimina las solicitudes de Ajax usando JavaScript usando jQuery 

Aquí está el código simple con el que estoy trabajando:

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

Básicamente, si se dispara un evento de keyup antes de que la función obtainFriendlist devuelva un resultado (y active UIDisplayFriends (msg), necesito cancelar la solicitud en vuelo. El problema que he tenido es que se acumulan, y de repente la función UIDisplayFriends se dispara repetidamente.

Muchas gracias, y el consejo también es útil


32
2017-11-05 22:50


origen


Respuestas:


El valor de retorno de $.ajax es un objeto XHR al que puedes llamar acciones. Para abortar la función, harías algo como:

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

También puede ser inteligente agregar algunos antirrebote para facilitar la carga en el servidor. Lo siguiente solo enviará una llamada XHR solo después de que el usuario haya dejado de escribir durante 100 ms.

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);
});

Una tercera cosa que realmente debería hacer es filtrar las respuestas XHR en función de si la solicitud sigue siendo válida o no:

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);
       }
     });
}

20
2017-11-05 22:58



¿Qué tal si usamos una variable, digamos isLoading, que establece en true utilizando la opción beforeSend (jqXHR, configuración) para .ajax, y luego usando la configuración completa para volver a establecer la variable en false. ¿Entonces solo valida con esa variable antes de activar otra llamada 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; }
     });
}

0
2017-11-05 22:56