3847 Stimmen

Was ist die JavaScript-Version von sleep()?

Gibt es einen besseren Weg zur Entwicklung einer sleep in JavaScript als die folgenden pausecomp Funktion ( entnommen von hier )?

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

Es handelt sich nicht um ein Duplikat von Sleep in JavaScript - Verzögerung zwischen Aktionen Ich möchte eine echter Schlaf in der Mitte einer Funktion und nicht eine Verzögerung, bevor ein Teil des Codes ausgeführt wird.

5475voto

Dan Dascalescu Punkte 125523

Aktualisierung 2017 - 2021

Seit 2009, als diese Frage gestellt wurde, hat sich JavaScript erheblich weiterentwickelt. Alle anderen Antworten sind inzwischen veraltet oder zu kompliziert. Hier ist die aktuell beste Praxis:

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

Oder als Einzeiler:

await new Promise(r => setTimeout(r, 2000));

Oder

const sleep = ms => new Promise(r => setTimeout(r, ms));

Verwenden Sie es als:

await sleep(<duration>);

Demo:

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

async function demo() {
    for (let i = 0; i < 5; i++) {
        console.log(`Waiting ${i} seconds...`);
        await sleep(i * 1000);
    }
    console.log('Done');
}

demo();

Beachten Sie das,

  1. await kann nur in Funktionen ausgeführt werden, denen das Präfix async Schlüsselwort oder auf der obersten Ebene Ihres Skripts in eine zunehmende Anzahl von Umgebungen .
  2. await pausiert nur die aktuelle async Funktion. Das bedeutet, dass die Ausführung des restlichen Skripts nicht blockiert wird, was Sie in den meisten Fällen wünschen. Wenn Sie ein blockierendes Konstrukt wünschen, siehe diese Antwort mit Atomics.wait aber beachten Sie, dass die meisten Browser dies im Haupt-Thread des Browsers nicht zulassen.

Zwei neue JavaScript-Funktionen (Stand 2017) halfen beim Schreiben dieser "Sleep"-Funktion:

Kompatibilität

Wenn Sie aus irgendeinem Grund Node älter als 7 verwenden (das die Ende des Lebens im Jahr 2017 ), oder sie zielen auf alte Browser ab, async / await kann immer noch verwendet werden über Babel (ein Werkzeug, das transpilieren JavaScript + neue Funktionen in einfaches altes JavaScript), mit dem transform-async-to-generator Plugin.

868voto

Ben Flynn Punkte 17854

(Siehe die aktualisierte Antwort für 2016 )

Ich denke, es ist durchaus sinnvoll, eine Aktion auszuführen, zu warten und dann eine weitere Aktion auszuführen. Wenn Sie es gewohnt sind, in Sprachen mit mehreren Threads zu schreiben, haben Sie wahrscheinlich die Idee, die Ausführung für eine bestimmte Zeitspanne zu unterbrechen, bis Ihr Thread aufwacht.

Das Problem dabei ist, dass JavaScript ein ereignisbasiertes Single-Thread-Modell ist. Während es in einem speziellen Fall schön sein kann, die gesamte Engine für ein paar Sekunden warten zu lassen, ist es im Allgemeinen eine schlechte Praxis. Angenommen, ich möchte Ihre Funktionen nutzen, während ich meine eigenen schreibe. Wenn ich Ihre Methode aufrufe, würden meine Methoden alle einfrieren. Wenn JavaScript irgendwie den Ausführungskontext Ihrer Funktion bewahren könnte, ihn irgendwo speichern, ihn dann zurückholen und später fortsetzen könnte, dann könnte sleep passieren, aber das wäre im Grunde Threading.

So sind Sie ziemlich viel stecken mit, was andere vorgeschlagen haben - Sie müssen Ihren Code in mehrere Funktionen aufteilen.

Ihre Frage ist also eine falsche Entscheidung. Es gibt weder eine Möglichkeit, so zu schlafen, wie Sie es wünschen, noch sollten Sie die von Ihnen vorgeschlagene Lösung verfolgen.

817voto

Nosredna Punkte 78203

In JavaScript schreibe ich jede Funktion so um, dass sie so schnell wie möglich beendet werden kann. Sie wollen, dass der Browser wieder die Kontrolle hat, damit er Ihre DOM-Änderungen vornehmen kann.

Jedes Mal, wenn ich einen Ruhezustand in der Mitte meiner Funktion haben wollte, habe ich umstrukturiert, um eine setTimeout() .

bearbeiten

Die berühmt-berüchtigte Funktion des Schlafens oder der Verzögerung in jeder Sprache ist sehr umstritten. Einige werden sagen, dass es immer ein Signal oder einen Rückruf geben sollte, um eine bestimmte Funktionalität auszulösen, andere werden argumentieren, dass manchmal ein willkürlicher Moment der Verzögerung nützlich ist. Ich sage, jedem das Seine, und eine Regel kann in dieser Branche nie etwas vorschreiben.

Das Schreiben einer Sleep-Funktion ist einfach und wird durch JavaScript Promises noch benutzerfreundlicher:

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

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

346voto

StephaneAG Punkte 937

Unter Firebug (und wahrscheinlich auch andere JavaScript-Konsolen), passiert nach dem Drücken der Eingabetaste nichts, erst nach der angegebenen Schlafdauer (...)

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

Beispiel für die Verwendung:

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

function sleepThenAct(){
    sleepFor(2000);
    console.log("Hello, JavaScript sleep!");
}

sleepThenAct()

Nota: Nur für Debugging und Entwicklung

207voto

DevinB Punkte 8160

Ich stimme den anderen Postern zu. Ein überfüllter Schlaf ist einfach eine schlechte Idee.

Allerdings hält setTimeout die Ausführung nicht auf. Die nächste Zeile der Funktion wird sofort nach dem Setzen der Zeitüberschreitung ausgeführt, nicht erst nach Ablauf der Zeitüberschreitung, so dass nicht dieselbe Aufgabe erfüllt wird, die ein Ruhezustand erfüllen würde.

Dazu müssen Sie Ihre Funktion in einen Vorher- und einen Nachher-Teil aufteilen.

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

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

Vergewissern Sie sich, dass Ihre Funktionsnamen immer noch genau beschreiben, was die einzelnen Teile tun (z. B. GatherInputThenWait und CheckInput, anstatt funcPart1 und funcPart2)

Mit dieser Methode wird der Zweck erreicht, dass die von Ihnen festgelegten Codezeilen erst dann ausgeführt werden, wenn nach Ihre Zeitüberschreitung, während gleichzeitig die Kontrolle an den Client-PC zurückgegeben wird, damit dieser alle anderen Aufgaben ausführen kann, die in der Warteschlange stehen.

Wie in den Kommentaren hervorgehoben wurde, wird dies absolut nicht funktionieren in einer Schleife. Sie könnten einige ausgefallene (hässlich) hacken, um es in einer Schleife arbeiten, aber im Allgemeinen, die nur für katastrophale Spaghetti-Code machen wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X