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.

2voto

Xeridea Punkte 1137

Ich weiß, die Frage ist über Schlaf, und klar die Antwort ist, dass es nicht möglich ist. Ich denke, dass ein allgemeiner Wunsch nach Schlaf darin besteht, asynchrone Aufgaben in der richtigen Reihenfolge zu erledigen; ich weiß, dass ich mit Sicherheit damit zu tun hatte.

In vielen Fällen kann es Versprechen verwenden ( Ajax fordert die gemeinsame Nutzung). Sie ermöglichen es Ihnen, asynchrone Dinge auf synchrone Weise zu tun. Es gibt auch eine Behandlung für Erfolg/Fehlschlag, und sie können verkettet werden.

Sie sind Teil von ECMAScript 6, so dass die Browserunterstützung noch nicht ganz ausgereift ist, vor allem der Internet Explorer unterstützt sie nicht. Es gibt auch eine Bibliothek namens Q für Versprechen.

Referenzen:

1voto

Aaron Punkte 1993

Wenn Sie eine anonyme Funktion wie eine, die Sie als Handler erstellt haben, schlafen wollen, empfehle ich Folgendes:

function()
{
    if (!wait_condition)
    {
        setTimeout(arguments.callee, 100, /* Comma-separated arguments here */);
    }
    // The rest of the function
}

Dieser Code besagt: "Wenn die Wartebedingung noch nicht erfüllt ist, rufen Sie diese Funktion erneut mit diesen Argumenten auf." Ich habe diese Methode verwendet, um dieselben Argumente an meine Handler zu übergeben, was diesen Code effektiv zu einem nicht-pollenden sleep() macht (der nur am Anfang Ihrer Funktion funktioniert).

1voto

Jared Dykstra Punkte 3526

TypeScript verwenden:

Hier ist eine kurze sleep() Umsetzung, die abgewartet werden kann. Dies ist der oberen Antwort so ähnlich wie möglich. Sie ist funktional äquivalent, außer dass ms wird getippt als number für TypeScript.

const sleep = (ms: number) =>
  new Promise((resolve) => setTimeout(resolve, ms));

async function demo() {
  console.log('Taking a break for 2s (2000ms)...');
  await sleep(2000);
  console.log('Two seconds later');
}

demo();

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

Beachten Sie das,

  1. await kann nur in Funktionen ausgeführt werden, die mit dem Präfix async Schlüsselwort, oder bei der oberste Ebene Ihres Skripts in einigen Umgebungen (z. B. in der Chrome DevTools-Konsole oder in Runkit).
  2. await pausiert nur die aktuelle async Funktion.

1voto

sfscs Punkte 496

Wenn Sie wirklich wollen, um den Haupt-Thread insgesamt zu blockieren und halten Sie die Ereignis-Schleife aus der Ereignis-Warteschlange zu ziehen, hier ist ein schöner Weg, um das zu tun, ohne die Erstellung von Funktionen, neue Date-Objekte oder undichte alle Variablen. Ich weiß, dass es bereits eine Million Antworten auf diese dumme Frage gibt, aber ich habe niemanden gesehen, der genau diese Lösung verwendet. Dies ist nur für moderne Browser.

Warnung : Dies ist nichts, was Sie jemals in der Produktion einsetzen würden. Es ist nur hilfreich für das Verständnis der Browser-Ereignisschleife. Sie ist wahrscheinlich nicht einmal für Tests nützlich. Es ist nicht wie eine normale System-Schlaf-Funktion, weil die JavaScript-Laufzeit ist immer noch die Arbeit jeden Zyklus.

for (let e = performance.now() + 2000; performance.now() < e; ) {}

Hier wird der setTimeout-Callback erst mindestens zwei Sekunden später aufgerufen, obwohl er fast sofort in die Ereigniswarteschlange eintritt:

setTimeout(function() {
  console.log("timeout finished");
}, 0);

for (let e = performance.now() + 2000; performance.now() < e; ) {}
console.log("haha wait for me first");

Sie werden eine Pause von etwa zwei Sekunden erleben und dann sehen:

haha wait for me first
timeout finished

Der Vorteil der Verwendung von performance.now() gegenüber Date.now() ist, dass das Date-Objekt

unterliegt sowohl dem Taktversatz als auch der Anpassung des Systemtakts. Der Wert der Zeit ist nicht immer monoton steigend und die nachfolgenden Werte können entweder sinken oder gleich bleiben. *

Im Allgemeinen ist performance.now() besser geeignet, um Zeitunterschiede mit hoher Genauigkeit zu messen.

Mit einer for Schleife hat den Vorteil, dass Sie vor der Ausführung lokale Variablen für den Block setzen können. Dadurch können Sie die Additionsberechnungen außerhalb der Schleife durchführen und sind trotzdem ein "Einzeiler". Dies sollte hoffentlich die CPU-Belastung durch diesen heißen Zyklus minimieren.

1voto

Henke Punkte 2647

Was ist die JavaScript-Version von sleep()?

Diese Frage wurde bereits beantwortet in die derzeit akzeptierte Antwort :

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

Zwei asynchrone Funktionen, die gleichzeitig laufen

Es ist eine gute Idee, sie innerhalb einer Funktion zu platzieren sleep() und dann await sleep() .
Um sie zu verwenden, ist ein wenig Kontext erforderlich:

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

(async function slowDemo () {
  console.log('Starting slowDemo ...');
  await sleep(2000);
  console.log('slowDemo: TWO seconds later ...');
})();

(async function fastDemo () {
  console.log('Starting fastDemo ...');
  await sleep(500);
  for (let i = 1; i < 6; i++) {
    console.log('fastDemo: ' + (i * 0.5) + ' seconds later ...');
    await sleep(500);
  }
})();

.as-console-wrapper { max-height: 100% !important; top: 0; }

Zwei asynchrone Aufrufe, die nacheinander ablaufen

Aber nehmen wir an slowDemo führt zu einem Ergebnis, das fastDemo abhängt.
In einem solchen Fall, slowDemo muss zu Ende laufen, bevor fastDemo beginnt:

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

(async () => {
  await (async function slowDemo () {
    console.log('Starting slowDemo ...');
    await sleep(2000);
    console.log('slowDemo: TWO seconds later ... completed!');
  })();

  (async function fastDemo () {
    console.log('Starting fastDemo ...');
    await sleep(500);
    let i = -2;
    for (i = 1; i < 5; i++) {
      console.log('fastDemo: ' + (i * 0.5) + ' seconds later ...');
      await sleep(500);
    }
    console.log('fastDemo: ' + (i * 0.5) + ' seconds later. Completed!');
  })();
})();

.as-console-wrapper { max-height: 100% !important; top: 0; }

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