Frage Was ist die JavaScript-Version von sleep ()?


Gibt es einen besseren Weg, ein sleep in JavaScript als das Folgende pausecomp Funktion (von hier genommen)

function pausecomp(millis)
{
    var date = new Date();
    var curDate = null;
    do { curDate = new Date(); }
    while(curDate-date < millis);
}

Dies ist kein Duplikat von Sleep in JavaScript - Verzögerung zwischen Aktionen; ich will ein richtiger Schlaf in der Mitte einer Funktion und nicht eine Verzögerung, bevor ein Code ausgeführt wird.


1519
2017-10-07 09:44


Ursprung


Antworten:


2017 Aktualisierung

Seit 2009, als diese Frage gestellt wurde, hat sich JavaScript deutlich weiterentwickelt. Alle anderen Antworten sind jetzt veraltet oder übermäßig kompliziert. Hier ist die aktuelle Best Practice:

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function demo() {
  console.log('Taking a break...');
  await sleep(2000);
  console.log('Two second later');
}

demo();

Das ist es. await sleep(<duration>).

Sie können diesen Code live ausprobieren auf Runkit. Beachten Sie, dass,

  1. await kann nur in Funktionen ausgeführt werden, denen das Präfix vorangestellt ist async Stichwort. Runkit wickelt Ihren Code vor der Ausführung in eine asynchrone Funktion ein.
  2. await unterbricht nur den Strom async Funktion

Zwei neue JavaScript-Funktionen halfen dabei, diese eigentliche "Schlaf" -Funktion zu schreiben:

Kompatibilität

Wenn Sie aus irgendeinem Grund einen älteren Knoten als 7 verwenden oder auf alte Browser zielen, async/await kann immer noch über verwendet werden Babel (Ein Werkzeug, das wird transpilieren JavaScript + neue Funktionen in einfachen alten JavaScript), mit der transform-async-to-generator Plugin. Lauf

npm install babel-cli --save

Erstellen .babelrc mit:

{
  "plugins": [
    "transform-async-to-generator",
  ]
}

Dann führe deinen Code mit aus

node_modules/babel-cli/bin/babel-node.js sleep.js

Aber auch hier brauchen Sie das nicht, wenn Sie Knoten 7 oder höher verwenden oder wenn Sie auf moderne Browser abzielen.


1071



(Siehe aktualisierte Antwort für 2016)

Ich denke, es ist völlig in Ordnung, eine Aktion durchführen zu wollen, zu warten und dann eine weitere Aktion durchzuführen. Wenn Sie es gewohnt sind, in Multi-Threaded-Sprachen zu schreiben, haben Sie wahrscheinlich die Idee, die Ausführung für eine bestimmte Zeit nachzugeben, bis Ihr Thread wieder aufwacht.

Das Problem hierbei ist, dass JavaScript ein ereignisbasiertes Single-Thread-Modell ist. In einem bestimmten Fall ist es vielleicht schön, dass die gesamte Engine einige Sekunden wartet, aber im Allgemeinen ist es eine schlechte Übung. Angenommen, ich wollte Ihre Funktionen nutzen, während ich meine eigenen schreibe? Wenn ich deine Methode anrief, würden meine Methoden alle einfrieren. Wenn JavaScript den Ausführungskontext Ihrer Funktion irgendwie beibehalten könnte, speichern Sie es irgendwo, dann bringen Sie es zurück und fahren Sie später fort, dann könnte Schlaf eintreten, aber das wäre im Grunde Threading.

Sie bleiben also bei dem, was andere vorgeschlagen haben - Sie müssen Ihren Code in mehrere Funktionen aufteilen.

Ihre Frage ist dann eine falsche Wahl. Es gibt keine Möglichkeit, so zu schlafen, wie Sie wollen, und Sie sollten auch nicht die von Ihnen vorgeschlagene Lösung verfolgen.


830



In JavaScript schreibe ich jede Funktion neu, damit sie so schnell wie möglich beendet werden kann. Sie möchten den Browser wieder unter Kontrolle haben, damit Ihr DOM Änderungen vornehmen kann.

Jedes Mal, wenn ich mitten in meiner Funktion einen Schlaf haben wollte, habe ich eine neue Funktion verwendet setTimeout().

Ich werde diese Antwort bearbeiten, weil ich das als nützlich empfand:

Der berüchtigte Schlaf oder die verzögerte Funktion in jeder Sprache wird viel diskutiert. Einige werden sagen, dass es immer ein Signal oder einen Rückruf geben sollte, um eine gegebene Funktionalität auszulösen, andere werden argumentieren, dass manchmal ein beliebiger Moment der Verzögerung nützlich ist. Ich sage, dass jeder seine eigene und eine Regel in dieser Branche nichts diktieren kann.

Das Schreiben einer Sleep-Funktion ist einfach und mit JavaScript-Versprechen noch besser nutzbar:

// sleep time expects milliseconds
function sleep (time) {
  return new Promise((resolve) => setTimeout(resolve, time));
}

// Usage!
sleep(500).then(() => {
    // Do something after the sleep!
});

590



Nur für debug / dev Ich poste das, wenn es jemandem nützlich ist

Interessante Sachen, in Firebug (und wahrscheinlich anderen js Konsolen) passiert nichts nach dem Drücken von Enter, nur nach der angegebenen Schlafdauer (...)

function sleepFor( sleepDuration ){
    var now = new Date().getTime();
    while(new Date().getTime() < now + sleepDuration){ /* do nothing */ } 
}

Anwendungsbeispiel:

function sleepThenAct(){ sleepFor(2000); console.log("hello js sleep !"); }

269



Ich stimme den anderen Plakaten zu, ein geschäftiger Schlaf ist nur eine schlechte Idee.

SetTimeout führt jedoch die Ausführung nicht aus, es führt die nächste Zeile der Funktion unmittelbar nach dem Timeout SET aus, nicht nach dem Ablauf des Timeouts, so dass die gleiche Aufgabe nicht ausgeführt wird, die ein Ruhezustand ausführen würde.

Der Weg, um es zu tun ist, um Ihre Funktion in vor und nach Teile zu zerlegen.

function doStuff()
{
  //do some things
  setTimeout(continueExecution, 10000) //wait ten seconds before continuing
}

function continueExecution()
{
   //finish doing things after the pause
}

Stelle sicher, dass deine Funktionsnamen immer noch genau beschreiben, was jedes Teil macht (I.E. GatherInputThenWait und CheckInput, anstatt funcPart1 und funcPart2)

Bearbeiten 

Diese Methode erreicht den Zweck, die Codezeilen, die Sie bis NACH Ihrer Zeitüberschreitung entscheiden, nicht auszuführen, während die Kontrolle immer noch an den Client-PC zurückgegeben wird, um alle anderen Vorgänge auszuführen, die sich in der Warteschlange befinden.

Weiter Bearbeiten

Wie in den Kommentaren erwähnt, wird dies absolut NICHT in einer Schleife funktionieren. Du könntest ein bisschen (hässliches) Hacking machen, damit es in einer Schleife funktioniert, aber im Allgemeinen wird das nur für katastrophalen Spaghetti-Code sorgen.


164



Für die Liebe von $ DEITY bitte keine busy-wait sleep-Funktion machen. setTimeout und setInterval Mach alles was du brauchst.


113



Ich weiß, das ist eine alte Frage, aber wenn Sie (wie ich) Javascript mit Rhino verwenden, können Sie ...

try
{
  java.lang.Thread.sleep(timeInMilliseconds);
}
catch (e)
{
  /*
   * This will happen if the sleep is woken up - you might want to check
   * if enough time has passed and sleep again if not - depending on how
   * important the sleep time is to you.
   */
}

109