Infinite Timer Loop mit Javascript (kein setInterval)?

8

Ich wurde (von einem Freund) gebeten, einen Timer zu erstellen (unendlich, der jede Sekunde eine Zeile schreibt), aber ohne setInterval .

I löste es mit:

%Vor%

Und es funktioniert.

Das Problem ist, dass ich befürchte, dass es einen Erinnerungsdruck geben wird. Es erzeugt tatsächlich eine Rekursion und nach einer Weile (Woche oder so) - der Prozess wird viel Speicher verbrauchen. (Der Stapel wird nie freigegeben)

Wie kann ich meinen Code ändern, um nicht viel Speicherverbrauch zu haben?

    
Royi Namir 22.11.2012, 06:15
quelle

3 Antworten

10

Es ist keine Rekursion

Es kann wie Rekursion aussehen, aber setTimeout erstellt keine Rekursion.

Die Art und Weise, wie setTimeout funktioniert, ist, dass es sofort zurückkehrt. Der Aufruf von k endet also sofort mit der Freigabe seines Stacks.

Wenn die Zeitüberschreitung tatsächlich eintritt und der Aufruf von go erneut auftritt, erfolgt dies nicht von dem Punkt des vorherigen Aufrufs von k , sondern vom globalen Bereich *.

* Hinweis: Ich verwende hier nicht die strikte Bedeutung des Bereichs, wie in der ECMAScript-Spezifikation definiert. Was ich meine ist, dass der Aufruf von k so erfolgt, als ob Sie ihn in ein einfaches <script></script> -Tag geschrieben hätten: das heißt, außerhalb jeder anderen Funktionsaufrufe.

In Bezug auf Ihre Besorgnis über die Schließung

In Ihrem speziellen Fall gibt es sehr wenig, das tatsächlich in der von der Funktion k erstellten Schließung eingeschlossen ist. Der einzige signifikante Abschluss ist der Verweis auf die Argumente cb und myId . Und selbst dann dauert es nur etwa eine Sekunde:

%Vor%

Könnte einfacher sein

Ich sollte beachten, dass Ihr Code ziemlich verschachtelt ist. Es kann einfacher geschrieben werden und ohne die Verwendung von Closures überhaupt (minus der globalen Variable i), wenn Sie es einfach so schreiben:

%Vor%     
slebetman 22.11.2012, 06:20
quelle
5

Diese Zeile ist falsch:

  

Es erstellt tatsächlich eine Rekursion und nach einer Weile (Woche oder so) - der Prozess wird viel Speicher verbrauchen. (Der Stapel wird nie freigegeben)

Es erstellt nicht Rekursion, weil die Funktion vollständig beendet und dann erneut aufgerufen wird.

Rekursion stapelt sich übereinander

%Vor%

Der Stapel sieht so aus

%Vor%

Mit setTimeout führen Sie eine Funktion aus. Diese Funktion richtet ein Ereignis ein, damit die Funktion wieder ausgeführt werden kann - aber hier ist der wichtige Unterschied: Die Funktion wird vollständig beendet und ist weg [1]. DANN wird es wieder gerufen.

In der Ausführung unterscheidet es sich nicht viel davon:

%Vor%

setTimeout gibt dem Browser nur die Möglichkeit zu atmen, wenn Sie möchten. Eine Chance für den Bildschirm zu aktualisieren, andere Ereignisse zu verarbeiten. Es ist nicht, um die richtige Terminologie zu verwenden, block der Browser.

    
Jeremy J Starcher 22.11.2012 06:24
quelle
2

Dies erzeugt kein Speicherleck.

Tatsächlich ist es ein ziemlich allgemein verwendetes Konzept. Normalerweise erscheint es in dieser Form:

%Vor%

Wenn Sie häufig (hier alle 10 Millisekunden) nach etwas suchen möchten, kann es besser sein, dieses Muster anstelle von setInterval zu verwenden, da dies die Seitenleistung verbessern kann. Wenn Ihre Funktion zum Beispiel mehr als 10 Millisekunden benötigt und Sie setInterval(f, 10) verwenden, wird sie ständig aufgerufen. Wenn Sie jedoch das obige Muster setTimeout verwenden, stellt es zumindest sicher, dass der Prozessor zwischen jedem Aufruf eine Unterbrechung von 10 Millisekunden erhält, unabhängig davon, wie lange die Ausführung der Funktion dauert.

Siehe dieses Video (ab 7.46 Uhr) von Paul Irish für weitere Informationen über dieses Muster.

>     
Nathan Wall 22.11.2012 06:17
quelle