2010-06-15 5 views
5

J'ai construit un liveSearch avec la méthode jQuery.ajax(). À chaque événement de touche, il reçoit de nouvelles données de résultat du serveur.jQuery.ajax(): rejeter les requêtes lentes

Le problème est, lorsque je tape très rapidement, par exemple. "foobar" et la requête GET de "fooba" demandent plus de temps que la requête "foobar", les résultats de "fooba" sont affichés.

Pour gérer cela avec le paramètre de délai d'attente est impossible, je pense.

Quelqu'un at-il une idée de comment résoudre ce problème?

Répondre

1

Affectez un ID unique incrémentiel à chaque requête et affichez-les uniquement par ordre croissant. Quelque chose comme ceci:

var counter = 0, lastCounter = 0; 
function doAjax() { 
    ++counter; 
    jQuery.ajax(url, function (result) { 
    if (counter < lastCounter) 
     return; 
    lastCounter = counter; 
    processResult(result); 
    }); 
} 
0

Vous ne devez lancer la recherche lorsque l'utilisateur n'a pas tapé quoi que ce soit pendant un certain temps (500ms environ). Cela permettrait d'éviter le problème que vous rencontrez.

Un excellent plugin jQuery qui est exactement ce que fait delayedObserver:

http://code.google.com/p/jquery-utils/wiki/DelayedObserver

+0

Bon commentaire. Il ne garantit cependant pas de résoudre son problème si la différence dans les temps de réponse peut être supérieure à .5s (ce qui est facilement le cas avec un hébergement mutualisé très chargé). – Wim

0

Faites en sorte chaque annule la dernière. Cela peut être une annulation trop importante, mais lorsque la frappe ralentit, elle se déclenche.

0

Cela semble être une quantité intense de trafic pour envoyer une requête ajax pour chaque événement KeyUp. Vous devez attendre que l'utilisateur arrête de taper, probablement pendant au moins quelques centaines de millisecondes.

Ce que je voudrais faire est la suivante:

var ajaxTimeout; 

function doAjax() { 
    //Your actual ajax request code 
} 


function keyUpHandler() { 
    if (ajaxTimeout !== undefined) 
     clearTimeout(ajaxTimeout); 

    ajaxTimeout = setTimeout(doAjax, 200); 
} 

Vous pourriez avoir à jouer avec le temps d'attente réel, mais cette façon fonctionne très bien et ne nécessite pas d'autres plug-ins.

Editer: Si vous devez transmettre des paramètres, créez une fonction inline (fermeture).

... 
var fun = function() { doAjax(params...) }; 
ajaxTimeout = setTimeout(fun, 200); 
7

Vous pouvez stocker et .abort() la dernière demande lors du démarrage d'un nouveau, comme celui-ci:

var curSearch; 
$("#myInput").keyup(function() { 
    if(curSearch) curSearch.abort(); //cancel previous search 
    curSearch = $.ajax({ ...ajax options... }); //start a new one, save a reference 
}); 

La méthode $.ajax() retourne l'objet XmlHttpRequest, si juste s'y accrocher, et quand vous lancez la recherche suivante, abandonner la le précédent.

Questions connexes