¿Cómo configuro un temporizador para evitar la superposición de llamadas ajax?

Tengo una página donde los resquicios de búsqueda se muestran tanto en una grilla como en un mapa (usando KML generado sobre la marcha, superpuesto en un mapa de Google incrustado). He conectado esto para que funcione mientras el usuario escribe; aquí está el esqueleto de mi código, que funciona:

$(function() {
   //Wire up search textbox
    $('input.Search').bind("keyup", update);
});

update = function(e) {
   //Get text from search box
   //Pass to web method and bind to concessions grid
    $.ajax({  
        ...
        success: function(msg) {
            displayResults(msg, filterParams);
        },
    });

}

displayResults = function(msg, filterParams) {
       //Databind results grid using jTemplates
       //Show results on map: Pass parameters to KML generator and overlay on map
}

Dependiendo de la búsqueda, puede haber cientos de resultados; y entonces el trabajo que ocurre en displayResults consume mucho procesador tanto en el servidor (consultar la base de datos, compilar y simplificar el KML sobre la marcha) como en el cliente (enlazar datos con la cuadrícula de resultados, superponer KML grande archivos en el mapa).

Me gusta la inmediatez de obtener resultados progresivamente más pequeños a medida que escribo, pero me gustaría minimizar el número de veces que esto se actualiza. ¿Cuál es la forma más sencilla de introducir una demora de N segundos después de que el usuario deja de escribir, antes de ejecutar la función update ?

1

3 Respuestas

En lugar de llamar directamente a update() , llame a un contenedor que verifique si hay actualizaciones pendientes pendientes:

$('input.Search').bind("keyup", delayedUpdate);

function delayedUpdate() {
    if (updatePending) {
        clearTimeout(updatePending);
    }

    updatePending = setTimeout(update, 250);
}

function update() {
    updatePending = false;

    //$.ajax(...
}

También deberías agregar:

$('input.Search').bind("blur", update);

Esto hará una actualización inmediata cuando el usuario abandone el campo. Pero asegúrese de que también agrega manejo para el caso en que el usuario abandona el campo mientras hay una actualización demorada pendiente (cancele primero la actualización diferida).

3
agregado
Esto funciona perfectamente, gracias.
agregado el autor Herb Caudill, fuente

Como primera aproximación, ¿qué tal algo así como:

$('input.Search').bind("keyup", function() { setTimeout(update, 5) } );

(no estoy seguro acerca de la sintaxis exacta de setTimeout).

También puede mantener una variable para rastrear si el tiempo de espera ya se ha programado o no.

0
agregado
Eso incurrirá efectivamente en la misma cantidad de carga innecesaria, después de esperar 5 milisegundos.
agregado el autor Ates Goral, fuente

Puede usar Window.SetTimeOut (YourRefreshMethod), cuando se llama a YourRefereshMethod, se verificará el número de caracteres que se tipean hasta el momento, y se lo comparará con el contador, el contador comenzará con 0, por lo que la llamada inicial no hará nada aparte de actualizar el contador con el recuento actual de caracteres, la segunda vez que se llama a su método, se verificará el número de caracteres escritos, si coincide con el número anterior registrado por el contador, significa que el usuario no escribió nada nuevo y puede disparar su método Refresh; de lo contrario, actualizará el valor del contador

0
agregado
JavaScript - Comunidad española
JavaScript - Comunidad española
4 de los participantes

En este grupo hablamos de JavaScript. Partner: es.switch-case.com