Frage

Ich schreibe eine Webapp ( Firefox-kompatibel nur ), die lange Abfrage verwendet (über jQuery Ajax-Fähigkeiten) mehr oder weniger konstantes Updates vom Server an den Client zu senden. Ich bin besorgt über die Auswirkungen dieses Lauf für längere Zeit verlassen, sagen wir, den ganzen Tag oder über Nacht. Der Basiscode Skelett ist dies:

function processResults(xml)
{
    // do stuff with the xml from the server
}

function fetch()
{
    setTimeout(function ()
    {
        $.ajax({
            type: 'GET',
            url: 'foo/bar/baz',
            dataType: 'xml',
            success: function (xml)
            {
                processResults(xml);
                fetch();
            },
            error: function (xhr, type, exception)
            {
                if (xhr.status === 0)
                {
                console.log('XMLHttpRequest cancelled');
                }
                else
                {
                    console.debug(xhr);
                    fetch();
                }
            }
        });
    }, 500);
}

(Der halbe Sekunde „Schlaf“ ist so, dass der Client den Server nicht hämmern, wenn die Updates kommen schnell zurück an den Client -., Die sie in der Regel sind)

Nach dieser Laufen über Nacht verlassen, neigt sie Firefox Crawl zu machen. Ich habe gedacht, dass dies könnte teilweise durch eine große Stack-Tiefe verursacht werden, da ich im Grunde eine unendlich rekursive Funktion geschrieben habe. Allerdings, wenn ich Firebug und einen Haltepunkt in fetch werfen, sieht es aus wie das nicht der Fall ist. Der Stapel dass Firebug zeigt mir nur etwa 4 oder 5 Frames tief, auch nach einer Stunde.

Eine der Lösungen, die ich überlege ich ist meine rekursive Funktion zu einem iterativen einer Veränderung, aber ich kann nicht herausfinden, wie ich die Verzögerung zwischen Ajax-Anfragen einfügen würde ohne Spinnen . Ich habe auf der JS 1.7 „Ausbeute“ keyword aber ich kann nicht ganz einwickeln mein Kopf herum, um herauszufinden, ob es ist, was ich brauche hier.

Ist die beste Lösung nur auf der Seite eine harte refresh zu tun in regelmäßigen Abständen, sagt, einmal pro Stunde? Gibt es ein besseres / schlankeren Lang Polling-Entwurfsmuster, die keinen Schmerz auf dem Browser auch nach der Ausführung für 8 oder 12 Stunden gestellt werden? Oder sollte ich einfach überspringen die lange Abfrage zusammen und verwenden eine andere „ständige Aktualisierung“ -Muster, da ich in der Regel wissen, wie oft der Server eine Antwort für mich haben?

War es hilfreich?

Lösung

Es ist auch möglich, dass es Firebug. Du console.logging Sachen, welche Mittel Sie wahrscheinlich ein Netzwerk-Monitor Registerkarte öffnen, etc. haben, die jede Anforderung bedeutet, wird im Speicher gespeichert.

Versuchen Sie es zu deaktivieren, zu sehen, ob das hilft.

Andere Tipps

Ich vermute, dass der Speicher von processResults() undicht ist.

Ich habe in einer lang Polling Webanwendung sehr ähnlichen Code zu Sie wurde verwenden, die in der Lage ist, ohne eine Aktualisierung der Seite ohne Unterbrechung für Wochen.

Ihr Stapel sollte nicht tief sein, weil fetch() kehrt sofort zurück. Sie benötigen keine unendlich rekursive Schleife haben.

können Sie wollen die Firefox Leak Monitor-Add-on verwenden unterstützen Sie Speicherlecks zu finden.

Die Stack-Tiefe von 4-5 ist richtig. setTimeout und $.ajax sind asynchrone Aufrufe, die sofort zurück. Der Rückruf wird später durch den Browser mit einem leeren Call-Stack genannt. Da Sie nicht lange Abfrage in einer synchronen Art und Weise implementieren können, müssen Sie diesen rekursive Ansatz. Es gibt keine Möglichkeit, es iterative zu machen.

Ich vermute, dass der Grund für diese Verlangsamung ist, dass der Code ein Speicherleck hat. Das Leck entweder in $.ajax von jQuery (sehr unwahrscheinlich) oder in Ihrem processResults Anruf sein könnte.

Es ist eine schlechte Idee fetch() aus dem Innern der Methode selbst zu nennen. Rekursivität wird besser genutzt, wenn Sie erwarten, dass das Verfahren irgendwann ein Ende erreichen und die Ergebnisse werden beginnen an den Anrufer senden werden. Die Sache ist, wenn Sie die Methode aufrufen rekursiv es den Anrufer Verfahren offen und mit Speicher hält. Wenn Sie nur 3-4 Frames tief sind, ist es, weil jQuery oder der Browser sind irgendwie „Fixierung“, was du getan hast.

Neue Versionen von jquery Unterstützung lang Polling standardmäßig. Auf diese Weise können Sie sicher sein, dass yhou nicht mit Ihrem unendlichen rekursiven Aufruf auf Browsers Intelligenz Deal deppending. Wenn die $.ajax() Methode aufrufen könnten Sie den Code verwenden, unten eine lange Umfrage mit einem sicheren Wartezeit von 500 Millisekunden, bevor ein neuer Anruf kombiniert zu tun.

function myLongPoll(){
    setTimeout(function(){
        $.ajax({
            type:'POST',
            dataType: 'JSON',
            url: 'http://my.domain.com/action',
            data: {},
            cache: false,
            success:function(data){

                //do something with the result

            },
            complete: myLongPoll, 
            async : false,
            timeout: 5000
        });
   //Doesn't matter how long it took the ajax call, 1 milisec or 
   //5 seconds (timeout), the next call will only happen after 2 seconds
   }, 2000);

Auf diese Weise können Sie sicher sein, dass die $.ajax() Anruf, bevor die nächste beginnt geschlossen ist. Dies kann durch Hinzufügen einer einfachen console.log() am Stand und ein anderer nach dem $.ajax() Aufruf nachgewiesen werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top