2010-06-15 13 views
5

Ich habe eine Live-Suche mit der jQuery.ajax() -Methode erstellen. Bei jedem keyup-Ereignis erhält es neue Ergebnisdaten vom Server.jQuery.ajax(): verwerfen langsame Anfragen

Das Problem ist, wenn ich sehr schnell tippe, z. "foobar" und die GET-Anfrage von "fooba" benötigt mehr Zeit als die "foobar" -Anfrage, die Ergebnisse von "fooba" werden angezeigt.

Um dies mit dem Timeout-Parameter umzugehen ist unmöglich, denke ich.

Hat jemand eine Idee, wie man das löst?

Antwort

1

Weisen Sie jeder Anforderung eine eindeutige, inkrementierende ID zu und zeigen Sie sie nur in aufsteigender Reihenfolge an. Etwas wie folgt aus:

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

Sie sollten nur die Suche starten, wenn der Benutzer etwas für eine Weile nicht getippt (500ms oder so). Dies würde das Problem verhindern, das Sie haben.

Eine ausgezeichnete jQuery-Plugin, das nur tut, ist delayedObserver:

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

+0

Guter Kommentar. Es garantiert jedoch nicht, sein Problem zu lösen, wenn der Unterschied in den Antwortzeiten größer als 0,5s sein kann (was bei hoch belastetem Shared Hosting leicht der Fall ist). – Wim

0

Machen Sie es sich so jeder die letzte aufhebt. Das könnte zu viel Abbruch sein, aber wenn man langsam tippt, wird es ausgelöst.

0

Das scheint eine intensive Menge an Verkehr zu senden eine Ajax-Anfrage für jedes KeyUp-Ereignis. Sie sollten warten, bis der Benutzer die Eingabe beendet hat - vermutlich mindestens für einige 100 Millisekunden.

Was ich tun würde, ist dies:

var ajaxTimeout; 

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


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

    ajaxTimeout = setTimeout(doAjax, 200); 
} 

Sie können mit der aktuellen Timeout-Zeit spielen, aber auf diese Weise funktioniert sehr gut und erfordert keine anderen Plugins.

Bearbeiten: Wenn Sie Parameter übergeben müssen, erstellen Sie eine Inline-Funktion (Schließung).

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

können Sie speichern und .abort() die letzte Anforderung, wenn eine neue starten, wie folgt aus:

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

Die $.ajax() Methode gibt das XmlHttpRequest Objekt, also nur auf sie hängen, und wenn Sie die nächste Suche zu starten, abbrechen die vorheriger.