2017-03-13 6 views
2

Ich bin ein JavaScript-Neuling und ich versuche, gleichzeitige Aktionen mit setInterval und setTimeout zu erreichen.Gleichzeitige Aktionen mit setInterval und setTimeout

Was ich erreichen möchte, was tatsächlich passiert und was ich erwartet habe, wird am besten mit dem folgenden Code erklärt.

var myVar = setInterval(function() { 
 
    myTimer() 
 
}, 1000); 
 

 
function myTimer() { 
 
    var d = new Date(); 
 
    var t = d.toLocaleTimeString(); 
 
    document.getElementById("demo").innerHTML = t; 
 
} 
 

 
for (var i = 0; i < 100; i++) { 
 
    setTimeout(function() { 
 
    console.log("log " + i); 
 
    }, 3000); 
 
}
<p>A script on this page starts this clock:</p> 
 
<p id="demo"></p>

Meine Erwartung für die führenden setInterval ist, dass die Funktion myTimer danach jede Sekunde, unabhängig von dem, was passiert, ausgeführt wird. Außer natürlich, wenn die Seite geschlossen ist oder clearTimeout auf myVar aufgerufen wird.

Ich kann nicht überprüfen, ob diese Aktion wirklich unabhängig und fortlaufend geschieht.

Die folgende for Schleife, gibt es weitere Code zu simulieren, um zu sehen, ob die myTimer Funktion unabhängig ausgeführt werden würde.

Ich erwartete die Schleife mit i=0 zu starten, dann drei Sekunden warten, log log 0 an die Konsole, dann weiter mit i=1 und so weiter.

Stattdessen wird das Timeout gestartet und in der Zwischenzeit hat i das Ende der for-Schleife erreicht und ist daher 100.

Wie bekomme ich die for-Schleife mit der Iteration für die setTimeout warten?

Und wird die setInterval wirklich jede Sekunde ausgeführt, unabhängig vom folgenden Code? Z.B. Wenn der folgende Code Aktionen hat, die etwas Zeit benötigen, wird die Uhr während der Verarbeitung trotzdem aktualisiert?

+0

können Sie hier nachschauen: http://StackOverflow.com/Questions/750486/Javascript-Closure-Inside-Loops-Simple-Practical-Beispiel –

+0

Ich werde darüber gehen, danke. Wenn ich es richtig verstehe, betrifft es die Iteration und die i-Variable. Hast du einen Kommentar zu meinen Fragen zu 'setInterval' und' setTimeout'? – MikeDyson

+1

Sie könnten dies auch nützlich finden [Gibt es eine Schlaffunktion in JavaScript?] (Http://stackoverflow.com/questions/1141302/is-there-a-sleep-function-in-javascript). Es sieht so aus, als ob Sie versuchen, die Ausführung mit settimeout zu unterbrechen - aber das wird nicht funktionieren, da settimeout die Ausführung nicht blockiert, indem es den Callback auf die Ereigniswarteschlange zu einem späteren Zeitpunkt setzt - der aktuelle Turn dann geht sofort weiter. –

Antwort

2

Sie können die Timeout-Zeit mit dem Faktor i ändern und einen Abschluss über i verwenden, um den richtigen Wert zu erhalten.

function myTimer() { 
 
    var d = new Date(); 
 
    var t = d.toLocaleTimeString(); 
 
    document.getElementById("demo").innerHTML = t; 
 
} 
 

 
var i, 
 
    myVar = setInterval(myTimer, 1000); 
 

 
for (i = 0; i < 100; i++) { 
 
    setTimeout(function (i) { 
 
     return function() { 
 
      console.log("log " + i); 
 
     }; 
 
    }(i), 3000 * i); 
 
}
<p>A script on this page starts this clock:</p> 
 
<p id="demo"></p>

Eine Version mit Timeout nach Timeout aufrufen.

function myTimer() { 
 
    var d = new Date(); 
 
    var t = d.toLocaleTimeString(); 
 
    document.getElementById("demo").innerHTML = t; 
 
} 
 

 
function next() { 
 
    i++; 
 
    console.log("log " + i); 
 
    if (i < 300) { 
 
     setTimeout(next, 3000); 
 
    } 
 
} 
 

 
var i = 0, 
 
    myVar = setInterval(myTimer, 1000); 
 

 
setTimeout(next, 3000);
<p>A script on this page starts this clock:</p> 
 
<p id="demo"></p>

+1

Das funktioniert genau so, wie ich meinen Code erwartet habe, aber ich kann mir nicht vorstellen, wie das funktioniert. Sie führen also in 'setTimeout' eine Funktion aus, die' 'eine Funktion zurückgibt, die die' console.log' ausführt? und multiplizierst du die Timeout-Zeit für jedes "i" mit 3000 ms? Entschuldigung - ich bin verloren. – MikeDyson

+0

rechts. die Schließung über "i" behält den Wert und die Multiplikation mit i verzögert den Aufruf der zurückgegebenen Funktion. –

+0

Bedeutet das, dass die for-Schleife sofort durch alle 100 'i's läuft und jedes Logbuch tatsächlich * irgendwo * gehalten wird, bis die 3 Sekunden *' i' abgelaufen sind, dann wird es ausgeführt? – MikeDyson

1

Über Ihre setInterval Frage, ja. Es wird jede Sekunde laufen (nicht Millisekunden gewissenhaft). Nehmen wir an, Sie setzen einfach setInterval und führen dann eine Aktion aus, die eine halbe Sekunde dauert. Das Intervall zählt diese halbe Sekunde und läuft nach einer weiteren halben Sekunde. Harte Code wird nicht die Uhr, ABER, verzögern, wenn Sie Code nur in dem Moment ausführen, dass das Intervall ausgelöst werden soll, wird es auf diesen Code warten, um zu beenden, da JavaScript single threaded ist. Das bedeutet, wenn Sie direkt nach dem Einstellen Ihres Intervalls Code ausführen, der länger als 1 Sekunde dauert, wird der Intervall-Callback danach ausgeführt, sodass er nicht innerhalb von 1 Sekunde ausgelöst wird. Nachfolgende Intervallaufrufe werden übrigens nicht nach diesem Intervall, sondern nach dem Setzen des Intervalls aufgerufen.Überprüfen Sie diese Geige (F12): https://jsfiddle.net/0gggmemu/4/

Sie sehen, dass das erste Intervall aufgerufen wird, wenn der Code endet, aber nachfolgende Intervalle werden aufgerufen, wenn das Intervall festgelegt wurde (Millisekunden überprüfen, wie sie das erste Protokoll anstelle des Starts passen) ein). Beachten Sie, dass die Intervalle nicht gestapelt sind. Wenn es zehn Intervalle hätte anrufen sollen, ruft es nur eins an und wartet auf das nächste. Wenn die Zeitgenauigkeit für Sie wichtig ist, sollten Sie beim Start eine Referenz speichern und den Unterschied in jedem Intervall überprüfen.

Über Gleichzeitigkeit, die gleiche wie wenn Sie setInterval aufrufen, wenn Sie setTimeout aufrufen, wird der Code seine Ausführung fortsetzen, Hunderte von Timeouts zur gleichen Zeit erstellen. Wenn Sie wollen, dass Code hängt, schauen Sie einfach auf meiner Geige nach. Übrigens, wenn Ihre Sorge über setTimeout Verriegelung setInterval ist, keine Sorge, da der Code nicht blockiert wird. Sie müssen sich nur etwas Sorgen machen, wenn Sie Code haben, der irgendwo stecken bleibt, aber in einer Callback-gesteuerten Anwendung ist es irgendwie schwierig, dies zu erreichen.

Verwandte Themen