molily: window.setTimeOut

Beitrag lesen

Hallo,

kann es sein, das wenn man diese Funktion aufruft, eine Art neuer Thread/Process geöffnet wird und mehrere Sachen Parallel ablaufen?

In JavaScript gibt es nur einen Thread und nichts wird wirklich parallel ausgeführt (Web Worker einmal ausgenommen). Man spricht von einem Event-Loop. Im Grunde ist das eine Warteschlange, die anstehende Funktionsaufrufe strikt nacheinander abarbeitet.

Mit setTimeout sorgt man dafür, dass die angegebene Funktion am Ende dieser Warteschlange eingefügt wird. Es wird erst der aktuelle Funktionsstapel abgearbeitet, dann mit der angegebenen Verzögerung die neue Funktion ausgeführt.

hierbei wird mir in dem Allert-Fenster diese Reihenfolge angezeigt:
stelle2
stelle1
stelle2
stelle2
stelle2

Das ist völlig logisch, ja. setTimeout sorgt dafür, dass »sup« wieder ausgeführt wird, nachdem »main« vollständig abgearbeitet ist.

So das Problem hierbei ist aber, dass wenn ich setTimeOut nicht benutze, werden mir die einzelnen durchläufe von sup() nicht angezeigt, sonder nur das Endprodukt.

Wahrscheinlich macht dein JavaScript DOM-Änderungen oder sonstige rechenintensive synchrone Dinge.

Solange ein JavaScript läuft, ist der Browser geblockt und rendert die Seite nicht neu. Änderungen am DOM werden i.d.R. erst sichtbar, wenn das JavaScript zum Stillstand gekommen ist. Wenn du 1000 Elemente erzeugst und nacheinander ohne Unterbrechung ins DOM einhängst, so sieht der Nutzer nicht eins nachdem anderen auftauchen, sondern sieht lange nichts und dann 1000 auf einen Schlag.

Wie kann ich es also hinbekommen, dass bei jedem durchlauf das Ergebnis auf der Seite angezeigt wird von Sup() und es dannach erst in main() weitergeht.

Letztlich ist die Lösung, asynchron und schrittweise zu arbeiten und dem Browser Zeit zu geben, zwischendrin die Seite zu rendern. setTimeout mit einem entsprechend hohem Verzögerungswert ist eine Möglichkeit, ausdrücklicher ist requestAnimationFrame. Das weist den Browser an, das Dokument auf den Bildschirm zu zeichnen, und dann asynchron mit dem nächsten Schritt weiterzumachen.

Vermutlich brauchst du eine Schleife, die eine bestimmte Operation wiederholt. Allerdings keine synchrone for- oder while-Schleife, sondern ein wiederholtes Aufrufen einer Schrittfunktion mit setTimeout/requestAnimationFrame, bis das Ende erreicht ist. Beispiel mit 100 Durchläufen (ungetestet, es geht ums Prinzip):

var i = 0, max = 100;  
var step = function () {};  
var loop = function () {  
  if (i < max) {  
    step();  
    requestAnimationFrame(loop);  
    i++;  
  } else {  
    end();  
  }  
};  
var end = function () {};

Hier wird die step-Funktion 100 mal aufgerufen, dazwischen wird mit requestAnimationFrame immer ein Rendering ausgelöst. Die loop-Funktion ruft sich immer wieder selbst auf mit requestAnimationFrame, bis 100 Durchläufe erreicht sind.

Siehe auch diesen Thread:
http://forum.de.selfhtml.org/archiv/2013/6/t214005/
Und mein Beispiel dort:
http://jsfiddle.net/molily/BfAVX/

Grüße,
Mathias