it-swarm.com.de

Was ist die JavaScript-Version von sleep ()?

Gibt es einen besseren Weg, um eine sleep in JavaScript zu konstruieren, als die 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 möchte einen echten Schlaf mitten in einer Funktion und keine Verzögerung, bevor ein Teil des Codes ausgeführt wird.

1984
fmsf

Aktualisierung 2017 - 2019

Seit 2009, als diese Frage gestellt wurde, hat sich JavaScript erheblich weiterentwickelt. Alle anderen Antworten sind jetzt veraltet oder zu 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 seconds later, showing sleep in a loop...');

  // Sleep in loop
  for (let i = 0; i < 5; i++) {
    if (i === 3)
      await sleep(2000);
    console.log(i);
  }
}

demo();_

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

Beachten Sie, dass,

  1. await kann nur in Funktionen ausgeführt werden, denen das Schlüsselwort async vorangestellt ist, oder in einigen Umgebungen (z. B. in den Chrome DevTools) auf der obersten Ebene Ihres Skripts Konsole oder Runkit).
  2. await unterbricht nur die aktuelle async Funktion

Zwei neue JavaScript-Funktionen haben beim Schreiben dieser "Schlaf" -Funktion geholfen:

Kompatibilität

Wenn Sie aus irgendeinem Grund Node verwenden, das älter als 7 ist (das Ende des Lebens erreicht hat), oder alte Browser als Ziel haben, async/await kann weiterhin über Babel (ein Tool, das transpiliert JavaScript + neue Funktionen in normales altes JavaScript umwandelt) verwendet werden, wobei transform-async-to-generator Plugin.

1893
Dan Dascalescu

(Siehe aktualisierte Antwort für 2016 )

Ich denke, es ist vollkommen vernünftig, eine Aktion ausführen zu wollen, zu warten und dann eine weitere Aktion auszuführen. Wenn Sie es gewohnt sind, in Multithread-Sprachen zu schreiben, haben Sie wahrscheinlich die Idee, die Ausführung für eine festgelegte Zeitspanne zu verzögern, bis Ihr Thread aufwacht.

Das Problem hierbei ist, dass JavaScript ein ereignisbasiertes Single-Thread-Modell ist. In bestimmten Fällen kann es hilfreich sein, den gesamten Motor einige Sekunden warten zu lassen. Im Allgemeinen ist dies eine schlechte Übung. Angenommen, ich wollte Ihre Funktionen nutzen, während ich meine eigenen schreibe? Wenn ich Ihre Methode aufrief, würden meine Methoden alle einfrieren. Wenn JavaScript den Ausführungskontext Ihrer Funktion auf irgendeine Weise erhalten könnte, speichern Sie sie irgendwo, bringen Sie sie dann zurück und fahren Sie später fort, dann könnte es zu einem Ruhezustand kommen, aber das wäre im Grunde genommen Threading.

Sie stecken also ziemlich fest in dem, was andere vorgeschlagen haben - Sie müssen Ihren Code in mehrere Funktionen aufteilen.

Ihre Frage ist also eine falsche Wahl. Es gibt keine Möglichkeit, so zu schlafen, wie Sie es möchten, und Sie sollten auch die von Ihnen vorgeschlagene Lösung nicht weiterverfolgen.

843
Ben Flynn

In JavaScript habe ich jede Funktion neu geschrieben, damit sie so schnell wie möglich beendet wird. Sie möchten, dass der Browser wieder die Kontrolle über Ihre DOM-Änderungen hat.

Jedes Mal, wenn ich mitten in meiner Funktion schlafen wollte, überarbeitete ich die Verwendung von setTimeout().

Ich werde diese Antwort bearbeiten, da ich dies als nützlich empfand:

Die berüchtigten Schlaf- oder Verzögerungsfunktionen in jeder Sprache sind 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, dass jeder seine eigene und eine Regel niemals etwas in dieser Branche vorschreiben kann.

Das Schreiben einer Sleep-Funktion ist einfach und mit 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!
});
628
Nosredna

Nur für Debug/Dev, ich poste dies, wenn es für jemanden nützlich ist

Interessante Sachen, in Firebug (& wahrscheinlich anderen js-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 */ } 
}

Anwendungsbeispiel:

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

Ich bin mit den anderen Postern einverstanden, ein beschäftigter Schlaf ist nur eine schlechte Idee.

SetTimeout hält jedoch die Ausführung nicht an, sondern führt die nächste Zeile der Funktion unmittelbar nach dem Festlegen des Zeitlimits aus, nicht nach Ablauf des Zeitlimits, sodass nicht die gleiche Aufgabe ausgeführt wird, die ein Ruhezustand ausführen würde.

Die Art und Weise, dies zu tun, besteht darin, Ihre Funktion in Teile vor und nach zu unterteilen.

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

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

Stellen Sie sicher, dass Ihre Funktionsnamen immer noch genau beschreiben, was jedes Teil tut (z. B. GatherInputThenWait und CheckInput anstelle von funcPart1 und funcPart2).

Bearbeiten

Mit dieser Methode wird der Zweck erreicht, dass die von Ihnen festgelegten Codezeilen erst NACH Ihrer Zeitüberschreitung ausgeführt werden, während die Steuerung weiterhin an den Client-PC zurückgegeben wird, um alles auszuführen, was sich in der Warteschlange befindet.

weitere Bearbeitung

Wie in den Kommentaren erwähnt, wird dies in einer Schleife absolut NICHT funktionieren. Sie könnten ein paar ausgefallene (hässliche) Hacker-Aktionen ausführen, damit es in einer Schleife funktioniert, aber im Allgemeinen führt dies nur zu einem katastrophalen Spaghetti-Code.

171
DevinB

Aus Liebe zu $ ​​DEITY machen Sie bitte keine "busy-wait sleep" -Funktion. setTimeout und setInterval tun alles, was Sie brauchen.

121
chaos

Ich weiß, dass dies eine alte Frage ist, 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.
   */
}
111
mjaggard

Wenn Sie jQuery verwenden, hat tatsächlich jemand ein "Delay" -Plugin erstellt, das nichts weiter als ein Wrapper für setTimeout ist:

// Delay Plugin for jQuery
// - http://www.evanbot.com
// - © 2008 Evan Byrne

jQuery.fn.delay = function(time,func){
    this.each(function(){
        setTimeout(func,time);
    });

    return this;
};

Sie können es dann wie erwartet in einer Reihe von Funktionsaufrufen verwenden:

$('#warning')
.addClass('highlight')
.delay(1000)
.removeClass('highlight');
68
Alan Plum

Ich habe auch nach einer Schlaflösung gesucht (nicht nach Produktionscode, nur nach Entwicklern/Tests) und diesen Artikel gefunden:

http://narayanraman.blogspot.com/2005/12/javascript-sleep-or-wait.html

... und hier noch ein Link zu clientseitigen Lösungen: http://www.devcheater.com/

Wenn Sie alert() aufrufen, wird Ihr Code ebenfalls angehalten, während ein Alarm angezeigt wird. Sie müssen eine Möglichkeit finden, um den Alarm nicht anzuzeigen, aber den gleichen Effekt zu erzielen. :)

43
a_w

Bitte schön. Seien Sie, wie der Code sagt, kein schlechter Entwickler und verwenden Sie dies auf Websites. Es ist eine Entwicklungshilfsfunktion.

// Basic sleep function based on ms.
// DO NOT USE ON PUBLIC FACING WEBSITES.
function sleep(ms) {
    var unixtime_ms = new Date().getTime();
    while(new Date().getTime() < unixtime_ms + ms) {}
}
29
Ian Maddox

Hier ist eine einfache Lösung mit einem synchronen XMLHttpRequest:

function sleep(n){
  var request = new XMLHttpRequest();
  request.open('GET', '/sleep.php?n=' + n, false);  // `false` makes the request synchronous
  request.send(null);
}

inhalt von sleep.php:

<?php sleep($_GET['n']);

Nenne es jetzt mit: sleep (5);

28
pguardiario

Zuerst:

Definieren Sie eine Funktion, die Sie folgendermaßen ausführen möchten:

function alertWorld(){
  alert("Hello World");
}

Planen Sie dann die Ausführung mit der Methode setTimeout:

setTimeout(alertWorld,1000)

Beachten Sie zwei Dinge

  • das zweite Argument ist die Zeit in Millisekunden
  • als erstes Argument müssen Sie nur den Namen (Referenz) der Funktion ohne Klammer übergeben
18
Pablo Fernandez

Ich persönlich mag das Einfache:

function sleep(seconds){
    var waitUntil = new Date().getTime() + seconds*1000;
    while(new Date().getTime() < waitUntil) true;
}

dann:

sleep(2); // Sleeps for 2 seconds

Ich benutze es die ganze Zeit, um falsche Ladezeiten beim Erstellen von Skripten in P5js zu erstellen

18
Akelian

Eine bessere Lösung, um Dinge so aussehen zu lassen, wie es die meisten Menschen wollen, ist die Verwendung einer anonymen Funktion:

alert('start');
var a = 'foo';
//lots of code
setTimeout(function(){  //Beginning of code that should run AFTER the timeout
    alert(a);
    //lots more code
},5000);  // put the timeout here

Dies ist wahrscheinlich der nächste Schritt zu etwas, das einfach das tut, was Sie wollen.

Hinweis: Wenn Sie mehrere Schlafplätze benötigen, kann dies schnell hässlich werden, und Sie müssen möglicherweise Ihr Design überdenken.

16
Mainguy

Ich würde setTimeOut in einem Promise for Code Consistency mit anderen asynchronen Tasks kapseln: Demo in Fiddle

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

So benutzt:

sleep(2000).then(function() { 
   // Do something
});

Es ist leicht, sich an die Syntax zu erinnern, wenn Sie früher Promises verwendet haben.

10
Elo

Für Browser stimme ich zu, dass setTimeout und setInterval der richtige Weg sind.

Für serverseitigen Code ist möglicherweise eine Sperrfunktion erforderlich (z. B., damit die Thread-Synchronisierung effektiv durchgeführt werden kann).

Wenn Sie node.js und meteor verwenden, sind Sie möglicherweise auf die Einschränkungen der Verwendung von setTimeout in einer Glasfaser gestoßen. Hier ist der Code für den serverseitigen Ruhezustand.

var Fiber = require('fibers');

function sleep(ms) {
    var fiber = Fiber.current;
    setTimeout(function() {
        fiber.run();
    }, ms);
    Fiber.yield();
}

Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

Siehe: https://github.com/laverdet/node-fibers#sleep

10
Homer6

Die meisten Antworten hier sind falsch oder zumindest veraltet. Es gibt keinen Grund, warum JavaScript als Singlethread ausgeführt werden muss, und das ist es auch nicht. Heutzutage unterstützen alle gängigen Browser Worker, bevor dies der Fall war, unterstützten andere Javascript-Laufzeiten wie Rhino und Node.js Multithreading.

"Javascript ist Single-Threaded" ist keine gültige Antwort. Das Ausführen einer Sleep-Funktion in einem Worker blockiert beispielsweise nicht den Code, der im UI-Thread ausgeführt wird.

In neueren Laufzeiten, die Generatoren und Ertrag unterstützen, könnten ähnliche Funktionen für die Sleep-Funktion in einer Umgebung mit nur einem Thread bereitgestellt werden:

// This is based on the latest ES6 drafts.
// js 1.7+ (SpiderMonkey/Firefox 2+) syntax is slightly different

// run code you want to sleep here (ommit star if using js 1.7)
function* main(){
    for (var i = 0; i < 10; i++) {
        // to sleep for 10 milliseconds 10 times in a row
        yield 10;
    }

    yield 5;
    console.log('I just slept 5 milliseconds!');
}

// resume the given generator after ms milliseconds
function resume(ms, generator){
    setTimeout(function(){
        // ommit .value if using js 1.7
        var nextSleep = generator.next().value;
        resume(nextSleep, generator);
    }, ms);
}

// initialize generator and get first sleep for recursive function
var
    generator = main(),
    firstSleep = generator.next().value;

// initialize recursive resume function
resume(firstSleep, generator);

Diese Nachahmung des Schlafes unterscheidet sich von einer echten Schlaffunktion, da sie den Thread nicht blockiert. Es ist einfach Zucker auf der aktuellen setTimeout-Funktion von Javascript. Dieser Funktionstyp wurde in Task.js implementiert und sollte heute in Firefox funktionieren.

9
Gabriel Ratener

Ich habe einige Webseiten auf Javascript durchsucht/gegoogelt. Sleep/wait ... und es gibt keine Antwort, wenn Sie Javascript auf "RUN, DELAY, RUN" setzen möchten stuff), RUN "oder" RUN, RUN + delayed RUN "....

Also aß ich ein paar Burger und überlegte:: Hier ist eine Lösung, die funktioniert ... aber Sie müssen Ihre laufenden Codes zerlegen ...:: Ja, ich weiß, dies ist nur ein einfacher zu lesendes Refactoring. . immer noch...

//......................................... //Beispiel 1:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setInterval
var i = 0;

function run() {
    //pieces of codes to run
    if (i==0){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==1){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i >2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" is ran</p>"; }
    if (i==5){document.getElementById("id1").innerHTML= "<p>all code segment finished running</p>"; clearInterval(t); } //end interval, stops run
    i++; //segment of code finished running, next...
}

run();
t=setInterval("run()",1000);

</script>
</body>
</html>

// .................................... // Beispiel 2:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout
var i = 0;

function run() {
    //pieces of codes to run, can use switch statement
    if (i==0){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(1000);}
    if (i==1){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(2000);}
    if (i==2){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>"; sleep(3000);}
    if (i==3){document.getElementById("id1").innerHTML= "<p>code segment "+ i +" ran</p>";} //stops automatically
    i++;
}

function sleep(dur) {t=setTimeout("run()",dur);} //starts flow control again after dur

run(); //starts
</script>
</body>
</html>

// ................. Beispiel3:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout
var i = 0;

function flow() {
    run(i);
    i++; //code segment finished running, increment i; can put elsewhere
    sleep(1000);
    if (i==5) {clearTimeout(t);} //stops flow, must be after sleep()
}

function run(segment) {
    //pieces of codes to run, can use switch statement
    if (segment==0){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==1){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment >2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
}

function sleep(dur) {t=setTimeout("flow()",dur);} //starts flow control again after dur

flow(); //starts flow
</script>
</body>
</html>

// .............. Beispiel4:

<html>
<body>
<div id="id1">DISPLAY</div>

<script>
//javascript sleep by "therealdealsince1982"; copyrighted 2009
//setTimeout, switch
var i = 0;

function flow() {
    switch(i)
    {
        case 0:
            run(i);
            sleep(1000);
            break;
        case 1:
            run(i);
            sleep(2000);
            break;
        case 5:
            run(i);
            clearTimeout(t); //stops flow
            break;
        default:
            run(i);
            sleep(3000);
            break;
    }
}

function run(segment) {
    //pieces of codes to run, can use switch statement
    if (segment==0){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==1){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment==2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    if (segment >2){document.getElementById("id1").innerHTML= "<p>code segment "+ segment +" is ran</p>"; }
    i++; //current segment of code finished running, next...
}

function sleep(dur) {t=setTimeout("flow()",dur);} //starts flow control again after dur

flow(); //starts flow control for first time...
</script>
</body>
</html>
8
user207408
function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}
7
Shemeer M Ali

Viele der Antworten beantworten die Frage nicht (direkt) und diese auch nicht ...

Hier sind meine zwei Cent (oder Funktionen):

Wenn Sie weniger klobige Funktionen als setTimeout und setInterval wünschen, können Sie sie in Funktionen einschließen, die einfach die Reihenfolge der Argumente umkehren und ihnen nette Namen geben:

function after(ms, fn){ setTimeout(fn, ms); }
function every(ms, fn){ setInterval(fn, ms); }

CoffeeScript-Versionen:

after = (ms, fn)-> setTimeout fn, ms
every = (ms, fn)-> setInterval fn, ms

Sie können sie dann mit anonymen Funktionen verwenden:

after(1000, function(){
    console.log("it's been a second");
    after(1000, function(){
        console.log("it's been another second");
    });
});

Jetzt heißt es leicht "nach N Millisekunden ..." (oder "alle N Millisekunden ...")

6
1j01

Ein Szenario, in dem Sie möglicherweise lieber eine sleep () - Funktion als setTimeout () verwenden möchten, besteht darin, dass Sie eine Funktion haben, die auf einen Benutzerklick reagiert und letztendlich ein neues Popup-Fenster öffnet und eine Verarbeitung initiiert hat, die einen kurzen Zeitraum erfordert abzuschließen, bevor das Popup angezeigt wird. Wenn Sie das geöffnete Fenster in eine Schließung verschieben, wird es normalerweise vom Browser blockiert.

6
acuth

Ich kann den Zweck einer Sleep-Funktion verstehen, wenn Sie sich mit synchroner Ausführung befassen müssen. Die Funktionen setInterval und setTimeout erstellen einen parallelen Ausführungsthread, der die Ausführungssequenz an das Hauptprogramm zurückgibt. Dies ist ineffektiv, wenn Sie auf ein bestimmtes Ergebnis warten müssen. Natürlich kann man Events und Handler verwenden, aber in manchen Fällen ist das nicht beabsichtigt.

6
naazgull

Dies kann mithilfe der Schlafmethode von Java erfolgen. Ich habe es in FF und IE getestet und es sperrt den Computer nicht, kaut keine Ressourcen und verursacht keine endlosen Server-Hits. Scheint mir eine saubere Lösung zu sein.

Zuerst müssen Sie Java auf die Seite laden und ihre Methoden verfügbar machen. Um das zu tun, habe ich folgendes getan:

<html>
<head>

<script type="text/javascript">

  function load() {
    var appletRef = document.getElementById("app");
    window.Java = appletRef.Packages.Java;
  } // endfunction

</script>

<body onLoad="load()">

<embed id="app" code="Java.applet.Applet" type="application/x-Java-applet" MAYSCRIPT="true" width="0" height="0" />

Dann müssen Sie nur noch Folgendes tun, wenn Sie eine schmerzfreie Pause in Ihrem JS wünschen:

Java.lang.Thread.sleep(xxx)

Wobei xxx die Zeit in Millisekunden ist. In meinem Fall (aus Gründen der Rechtfertigung) war dies Teil der Auftragsabwicklung bei einem sehr kleinen Unternehmen, und ich musste eine Rechnung drucken, die vom Server geladen werden musste. Ich habe die Rechnung (als Webseite) in einen iFrame geladen und dann den iFrame gedruckt. Natürlich musste ich warten, bis die Seite vollständig geladen war, bevor ich drucken konnte, also musste der JS pausieren. Dies wurde erreicht, indem die Rechnungsseite (im iFrame) ein ausgeblendetes Formularfeld auf der übergeordneten Seite mit dem Ereignis onLoad ändert. Und der Code auf der übergeordneten Seite zum Drucken der Rechnung sah folgendermaßen aus (irrelevante Teile wurden aus Gründen der Übersichtlichkeit herausgeschnitten):

var isReady = eval('document.batchForm.ready');
isReady.value=0;

frames['rpc_frame'].location.href=url;

while (isReady.value==0) {
  Java.lang.Thread.sleep(250);
} // endwhile

window.frames['rpc_frame'].focus();
window.frames['rpc_frame'].print();

Der Benutzer drückt den Knopf, das Skript lädt die Rechnungsseite, wartet dann und prüft jede Viertelsekunde, ob die Rechnungsseite vollständig geladen ist, und öffnet dann den Druckdialog, damit der Benutzer sie an den Drucker senden kann. QED.

6
Rachael

Hinzufügen meiner zwei Bits. Ich musste zu Testzwecken viel warten. Ich wollte den Code nicht aufteilen, da das eine Menge Arbeit wäre, also hat ein einfaches für es für mich getan.

for (var i=0;i<1000000;i++){                    
     //waiting
  }

Ich sehe keinen Nachteil darin und es hat den Trick für mich getan.

6
caiocpricci2

Sie können in JavaScript nicht so schlafen, oder sollten es lieber nicht. Wenn Sie eine Sleep- oder eine While-Schleife ausführen, bleibt der Browser des Benutzers hängen, bis die Schleife beendet ist.

Verwenden Sie einen Timer, wie in dem Link angegeben, auf den Sie verwiesen haben.

5
Andrew Dunkman

Für den speziellen Fall, dass Sie eine Reihe von Aufrufen, die von einer Schleife ausgeführt werden, löschen möchten, können Sie so etwas wie den folgenden Code mit dem Prototyp verwenden. Ohne Prototyp können Sie die Verzögerungsfunktion durch setTimeout ersetzen.

function itemHandler(item)
{
    alert(item);
}

var itemSet = ['a','b','c'];

// Each call to itemHandler will execute
// 1 second apart
for(var i=0; i<itemSet.length; i++)
{
    var secondsUntilExecution = i;
    itemHandler.delay(secondsUntilExecution, item)
}
5
beauburrier

Wenn Sie sich in node.js befinden, sehen Sie sich fibres - eine native C-Erweiterung für node an, eine Art Multithreading-Simulation.

Es ermöglicht Ihnen, eine echte sleep auf eine Weise auszuführen, die die Ausführung in einer Faser blockiert, im Haupt-Thread und in anderen Fasern jedoch nicht blockiert.

Hier ist ein Beispiel aus ihrer eigenen Readme-Datei:

// sleep.js

var Fiber = require('fibers');

function sleep(ms) {
    var fiber = Fiber.current;
    setTimeout(function() {
        fiber.run();
    }, ms);
    Fiber.yield();
}

Fiber(function() {
    console.log('wait... ' + new Date);
    sleep(1000);
    console.log('ok... ' + new Date);
}).run();
console.log('back in main');

- und die Ergebnisse sind:

$ node sleep.js
wait... Fri Jan 21 2011 22:42:04 GMT+0900 (JST)
back in main
ok... Fri Jan 21 2011 22:42:05 GMT+0900 (JST)
5
tomekwi

Eine alte Frage aus dem Jahr 2009. Ab 2015 ist eine neue Lösung mit Generatoren möglich, die in ECMAscript 2015 alias ES6 definiert sind. Es wurde im Juni genehmigt, aber zuvor in Firefox und Chrome implementiert. Jetzt kann eine Sleep-Funktion in Schleifen und Unterfunktionen verschachtelt werden, ohne den Browser einzufrieren. Es wird nur reines JavaScript benötigt, keine Bibliotheken oder Frameworks.

Das folgende Programm zeigt, wie sleep() und runSleepyTask() erstellt werden können. Die Funktion sleep() ist nur eine Anweisung yield. Es ist so einfach, dass es tatsächlich einfacher ist, die Anweisung yield direkt zu schreiben, anstatt sleep() aufzurufen, aber dann würde es kein Schlafwort geben :-) Die Ausbeute gibt einen Zeitwert für die Methode next() innerhalb von wakeup() und zurück wartet. Das eigentliche "Schlafen" geschieht in wakeup() unter Verwendung der guten alten setTimeout(). Beim Rückruf löst die Methode next() die Anweisung yield aus, um fortzufahren, und die "Magie" der Ausbeute besteht darin, dass alle lokalen Variablen und der gesamte Aufrufstapel um sie herum noch intakt sind.

Funktionen, die sleep () oder yield verwenden, müssen als Generatoren definiert werden. Einfach durch Hinzufügen eines Sterns zum Schlüsselwort function*. Einen Generator auszuführen ist etwas kniffliger. Wenn der Generator mit dem Schlüsselwort new aufgerufen wird, gibt er ein Objekt mit der Methode next() zurück, aber der Hauptteil des Generators wird nicht ausgeführt (das Schlüsselwort new ist optional und macht keinen Unterschied). Die Methode next() löst die Ausführung des Generatorkörpers aus, bis ein yield auftritt. Die Wrapper-Funktion runSleepyTask() startet das Ping-Pong: next() wartet auf eine yield und yield wartet auf eine next().

Ein anderer Weg, einen Generator aufzurufen, ist mit dem Schlüsselwort yield*, hier funktioniert es wie ein einfacher Funktionsaufruf, aber es beinhaltet auch die Möglichkeit, zu next() zurückzukehren.

Dies wird alles durch das Beispiel drawTree() demonstriert. Es zeichnet einen Baum mit Blättern auf einer rotierenden 3D-Szene. Ein Baum wird als Stamm mit 3 Teilen oben in verschiedene Richtungen gezeichnet. Jeder Teil wird dann als ein anderer, aber kleinerer Baum gezeichnet, indem nach einem kurzen Schlaf rekursiv drawTree() aufgerufen wird. Ein sehr kleiner Baum wird nur als Blatt gezeichnet.

Jedes Blatt hat sein eigenes Leben in einer separaten Aufgabe, die mit runSleepyTask() beginnt. Es wird geboren, wächst, sitzt, verblasst, fällt und stirbt in growLeaf(). Die Geschwindigkeit wird mit sleep() gesteuert. Dies zeigt, wie einfach Multitasking durchgeführt werden kann.

function* sleep(milliseconds) {yield milliseconds};

function runSleepyTask(task) {
    (function wakeup() {
        var result = task.next();
        if (!result.done) setTimeout(wakeup, result.value);
    })()
}
//////////////// written by Ole Middelboe  /////////////////////////////

pen3D =setup3D();
var taskObject = new drawTree(pen3D.center, 5);
runSleepyTask(taskObject);

function* drawTree(root3D, size) {
    if (size < 2) runSleepyTask(new growLeaf(root3D))
    else {
        pen3D.drawTrunk(root3D, size);
        for (var p of [1, 3, 5]) {
            var part3D = new pen3D.Thing;
            root3D.add(part3D);
            part3D.move(size).turn(p).tilt(1-p/20);
            yield* sleep(50);
            yield* drawTree(part3D, (0.7+p/40)*size);
        }
    }
}

function* growLeaf(stem3D) {
    var leaf3D = pen3D.drawLeaf(stem3D);
    for (var s=0;s++<15;) {yield* sleep(100); leaf3D.scale.multiplyScalar(1.1)}
    yield* sleep( 1000 + 9000*Math.random() );
    for (var c=0;c++<30;) {yield* sleep(200); leaf3D.skin.color.setRGB(c/30, 1-c/40, 0)}
    for (var m=0;m++<90;) {yield* sleep( 50); leaf3D.turn(0.4).tilt(0.3).move(2)}
    leaf3D.visible = false;
}
///////////////////////////////////////////////////////////////////////

function setup3D() {
    var scene, camera, renderer, diretionalLight, pen3D;

    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(75, 
        window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.set(0, 15, 20);
    renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    
    directionalLight = new THREE.DirectionalLight(0xffffaa, 0.7);
    directionalLight.position.set(-1, 2, 1);
    scene.add(directionalLight);
    scene.add(new THREE.AmbientLight(0x9999ff));
      
    (function render() {
        requestAnimationFrame(render);
        // renderer.setSize( window.innerWidth, window.innerHeight );
        scene.rotateY(10/60/60);
        renderer.render(scene, camera);
    })();
    
    window.addEventListener(
        'resize',
        function(){
            renderer.setSize( window.innerWidth, window.innerHeight );
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
       }, 
       false
    );
    
    pen3D = {
        drawTrunk: function(root, size) {
            // root.skin = skin(0.5, 0.3, 0.2);
            root.add(new THREE.Mesh(new THREE.CylinderGeometry(size/12, size/10, size, 16), 
                root.skin).translateY(size/2));
            root.add(new THREE.Mesh(new THREE.SphereGeometry(size/12, 16), 
                root.skin).translateY(size));
            return root;
        },
        
        drawLeaf: function(stem) {
            stem.skin.color.setRGB(0, 1, 0);
            stem.add(new THREE.Mesh(new THREE.CylinderGeometry(0, 0.02, 0.6), 
                stem.skin) .rotateX(0.3).translateY(0.3));
            stem.add(new THREE.Mesh(new THREE.CircleGeometry(0.2), 
                stem.skin) .rotateX(0.3).translateY(0.4));
            return stem;
        },
        
        Thing: function() {
            THREE.Object3D.call(this);
            this.skin = new THREE.MeshLambertMaterial({
                color: new THREE.Color(0.5, 0.3, 0.2),
                vertexColors: THREE.FaceColors,
                side: THREE.DoubleSide
            })
        }
    };

    pen3D.Thing.prototype = Object.create(THREE.Object3D.prototype);
    pen3D.Thing.prototype.tilt = pen3D.Thing.prototype.rotateX;
    pen3D.Thing.prototype.turn = pen3D.Thing.prototype.rotateY;
    pen3D.Thing.prototype.move = pen3D.Thing.prototype.translateY;
    
    pen3D.center = new pen3D.Thing;
    scene.add(pen3D.center);
    
    return pen3D;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>

Das 3D-Zeug ist in setup3D () versteckt und nur enthalten, um es weniger langweilig zu machen als console.log (). Engel werden übrigens im Bogenmaß gemessen.

Getestet für Firefox und Chrome. Nicht in Internet Explorer und iOS (iPads) implementiert. Versuche es selbst zu machen.

Nach einem erneuten Durchlauf der Antworten stellte ich fest, dass Gabriel Ratener vor einem Jahr eine ähnliche Antwort gegeben hatte: https://stackoverflow.com/a/24401317/5032384

5
Ole Middelboe

Code aus diesem Link wird comp nicht einfrieren. Aber es funktioniert nur bei ff.

/**
 * Netscape compatible WaitForDelay function.
 * You can use it as an alternative to Thread.Sleep() in any major programming language
 * that support it while JavaScript it self doesn't have any built-in function to do such a thing.
 * parameters:
 * (Number) delay in millisecond
 */
function nsWaitForDelay(delay) {
    /**
     * Just uncomment this code if you're building an extention for Firefox.
     * Since FF3, we'll have to ask for user permission to execute XPCOM objects.
     */
    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

    // Get the current thread.
    var thread = Components.classes["@mozilla.org/thread-manager;1"].getService(Components.interfaces.nsIThreadManager).currentThread;

    // Create an inner property to be used later as a notifier.
    this.delayed = true;

    /* Call JavaScript setTimeout function
      * to execute this.delayed = false
      * after it finish.
      */
    setTimeout("this.delayed = false;", delay);

    /**
     * Keep looping until this.delayed = false
     */
    while (this.delayed) {
        /**
         * This code will not freeze your browser as it's documented in here:
         * https://developer.mozilla.org/en/Code_snippets/Threads#Waiting_for_a_background_task_to_complete
         */
        thread.processNextEvent(true);
    }
}
4
CoR

Seit Node 7.6 können Sie die Funktion promisify aus dem Modul utils mit setTimeout kombinieren.

const sleep = require('util').promisify(setTimeout)

Allgemeine Verwendung

async function main() {
    console.time("Slept for")
    await sleep(3000)
    console.timeEnd("Slept for")
}

main()

Fragenverwendung

async function asyncGenerator() {
    while (goOn) {
      var fileList = await listFiles(nextPageToken);
      await sleep(3000)
      var parents = await requestParents(fileList);
    }
  }
4
Harry

Wenn Sie eine Schlaffunktion wie diese korrigieren

var sleep = function(period, decision, callback){
    var interval = setInterval(function(){
        if (decision()) {
            interval = clearInterval(interval);
            callback();
        }
    }, period);
}

und Sie haben eine asynchrone Funktion, um mehrere Male aufzurufen

var xhr = function(url, callback){
    // make ajax request
    // call callback when request fulfills
}

Und so richten Sie Ihr Projekt ein:

var ready = false;

function xhr1(){
    xhr(url1, function(){ ready = true;});  
}
function xhr2(){
    xhr(url2, function(){ ready = true; }); 
}
function xhr3(){
    xhr(url3, function(){ ready = true; }); 
}

Dann können Sie dies tun:

xhr1();
sleep(100, function(){ return done; }, xhr2);
sleep(100, function(){ return done; }, xhr3);
sleep(100, function(){ return done; }, function(){
    // do more
});

Anstelle einer endlosen Rückrufeinrückung wie folgt:

xhr(url1, function(){
    xhr2(url2, function(){
        xhr3(url3, function(){
            // do more
        });
    });
});
4
BishopZ

Zuallererst - setTimeout und setInterval sind das, was sollte verwendet werden, da Javascript ein Callback-Typ ist. Wenn Sie sleep() verwenden möchten, ist der Kontrollfluss oder die Architektur Ihres Codes falsch.

Trotzdem kann ich wohl noch bei zwei Umsetzungen eines Schlafes helfen.

  1. gefälschter Synchronlauf über meinem Kopf:

    //a module to do taht //dual-license: MIT or WTF [you can use it anyhow and leave my nickname in a comment if you want to]
    var _=(function(){
     var queue=[];
     var play=function(){
       var go=queue.shift();
         if(go){if(go.a){go.f();play();}else{setTimeout(play,go.t);}}
       }
     return {
       go:function(f){
        queue.Push({a:1,f:f});
        },
       sleep:function(t){
        queue.Push({a:0,t:t});
        },
       playback:play 
     }
    })();
    

    [Die automatische Wiedergabe sollte ebenfalls möglich sein.]

    //usage
    
    _.go(function(){
    
    //your code
    console.log('first');
    
    });
    
    
    _.sleep(5000);
    
    _.go(function(){
    
    //your code
    console.log('next');
    
    });
    
    //this triggers the simulation
    _.playback();
    
  2. echter Synchronlauf

Ich habe mir eines Tages viele Gedanken gemacht und die einzige Idee, die ich für einen echten Schlaf in Javascript hatte, ist technisch.

eine Sleep-Funktion müsste ein synchroner AJAX-Aufruf mit einer auf den Sleep-Wert festgelegten Zeitüberschreitung sein. Das ist alles und eine einzige Möglichkeit, eine echte sleep() zu haben.

4
naugtur

Falls Sie wirklich einen Schlaf brauchen (), nur um etwas zu testen. Beachten Sie jedoch, dass der Browser beim Debuggen die meiste Zeit abstürzt - wahrscheinlich benötigen Sie ihn deshalb sowieso. Im Produktionsmodus werde ich diese Funktion auskommentieren.

function pauseBrowser(millis) {
    var date = Date.now();
    var curDate = null;
    do {
        curDate = Date.now();
    } while (curDate-date < millis);
}

Verwenden Sie kein neues Datum () in der Schleife, es sei denn, Sie möchten Speicher, Rechenleistung, Akku und möglicherweise die Lebensdauer Ihres Geräts verschwenden.

3
Rodrigo

Eine Funktion zum Schlafen, die einen synchronen Aufruf verwendet, um das Betriebssystem dies tun zu lassen. Verwenden Sie einen beliebigen Befehl für den Ruhezustand des Betriebssystems. Es ist nicht mit Warten im Sinne von CPU-Zeit beschäftigt.

Ich habe mich für eine nicht existierende Adresse entschieden.

const cp = require('child_process');

function sleep(ms)
{ 
    try{cp.execSync('ping 192.0.2.0 -n 1 -w '+ms);}
    catch(err){}
}

Ein Test, um zu überprüfen, ob es funktioniert

console.log(Date.now());
console.log(Date.now());
sleep(10000);
console.log(Date.now());
console.log(Date.now());

Und einige Testergebnisse.

1491575275136
1491575275157

(und nach 10 Sekunden)

1491575285075
1491575285076
2
Ivan

Dies ist wirklich keine gute Idee. Wenn Sie so etwas tun, wird die gesamte Seite eingefroren, während das System auf die Rückkehr Ihrer Funktion gewartet hat.

2
Scimon

Wenn Sie eine Empfehlung wünschen, die Leistung nicht zu verlieren. setTimeout ist Ihre erwartete sleep. Wenn Sie jedoch eine Syntax wünschen, bei der der Code durch sleep "in der Mitte geteilt" wird, können wir Folgendes tun:

sleep=function(tm,fn){
   window.setTimeout(fn,tm);
}

dann funktioniert perpare wie folgt:

var fnBeforeSleep=function(){

 //All codes before sleep

}  

var fnAfterSleep=function(){

 //All codes after sleep

}  

Dann :

fnBeforeSleep();
sleep(2000,
fnAfterSleep);

JA! ٍ syntaktisch ist es sehr nah an:

fnBeforeSleep();
sleep(2000); 
fnAfterSleep();
2
Abdennour TOUMI

2019 Update mit Atomics.wait

Sollte in Node 9.3 oder höher funktionieren.

Ich brauchte einen ziemlich genauen Zeitgeber in Node.js und das funktioniert großartig. Es scheint jedoch, dass die Unterstützung in Browsern äußerst begrenzt ist.

let ms = 10000;
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);

Lief einige 10 Sekunden Timer Benchmarks.

Mit setTimeout erhalte ich einen Fehler von bis zu 7000 Mikrosekunden. (7 ms)

Bei Atomics scheint mein Fehler unter 600 Mikrosekunden zu bleiben. (0,6 ms)

2
Kapytanhook

Mit await Unterstützung und Bluebird Versprechen :

await bluebird.delay(1000);

Dies funktioniert wie ein synchrones sleep(1) der Sprache c. Meine Lieblingslösung.

2
Guang-De Lin
  await new Promise(resolve => setTimeout(resolve, 2000));

stellen Sie sicher, dass Ihre anrufende Funktion asynchron ist

verifiziert und funktioniert gut

2

Erleben Sie die asynchrone Natur von Javascript!

Alle folgenden Befehle kehren sofort zurück, verfügen jedoch über eine einzige Stelle zum Einfügen von Code, den Sie ausführen möchten, nachdem etwas geschehen ist.

Die Methoden, die ich hier skizziert habe, sind alle für verschiedene Anwendungsfälle und in ihrer Komplexität grob geordnet.

Die verschiedenen Dinge sind wie folgt:

  • Warten auf eine Bedingung, um wahr zu werden
  • Warten auf das Beenden einer Reihe von Methoden (in beliebiger Reihenfolge), bevor ein einzelner Rückruf aufgerufen wird
  • Ausführen einer Reihe von asynchronen Methoden mit gemeinsamem Status in einer bestimmten Reihenfolge, bevor ein Rückruf aufgerufen wird

Warte

Das Abwarten, ob eine Bedingung zutrifft, ist hilfreich, wenn kein verfügbarer Rückruf vorhanden ist, der Ihnen mitteilt, wann die Ausführung eines Vorgangs abgeschlossen ist.

Dies ist eine ziemlich grundlegende Implementierung, die davon ausgeht, dass die Bedingung irgendwann erfüllt wird. Mit wenigen Handgriffen kann es noch nützlicher erweitert werden (z. B. durch Festlegen eines Anruflimits). (Das habe ich erst gestern geschrieben!)

function waitFor(predicate, successCallback) {
    setTimeout(function () {
        var result = predicate();
        if (result !== undefined)
            successCallback(result);
        else
            waitFor(predicate, successCallback);
    }, 100);
}

vorwahl:

    beforeEach(function (done) {
        selectListField('A field');

        waitFor(function () {
            var availableOptions = stores.scrapeStore(optionStore);
            if (availableOptions.length !== 0)
                return availableOptions;
        }, done);
    });

Hier rufe ich etwas auf, das einen extjs-'Store 'lädt und warte, bis der Store etwas enthält, bevor ich fortfahre (der beforeEach ist eine Jasmin-Test-Framework-Sache).

Warten Sie, bis einige Dinge erledigt sind

Eine andere Sache, die ich tun musste, war, einen einzelnen Rückruf auszuführen, nachdem das Laden verschiedener Methoden abgeschlossen war. Das können Sie so machen:

createWaitRunner = function (completionCallback) {
    var callback = completionCallback;
    var completionRecord = [];
    var elements = 0;

    function maybeFinish() {
        var done = completionRecord.every(function (element) {
            return element === true
        });

        if (done)
            callback();
    }

    return {
        getNotifier: function (func) {
            func = func || function (){};

            var index = elements++;
            completionRecord[index] = false;

            return function () {
                func.applyTo(arguments);
                completionRecord[index] = true;
                maybeFinish();
            }
        }
    }
};

vorwahl:

    var waiter = createWaitRunner(done);

    filterList.bindStore = waiter.getNotifier();
    includeGrid.reconfigure = waiter.getNotifier(function (store) {
        includeStore = store;
    });
    excludeGrid.reconfigure = waiter.getNotifier(function (store) {
        excludeStore = store;
    });

Sie warten entweder nur auf die Benachrichtigungen oder können auch andere Funktionen umbrechen, die die an die Funktion übergebenen Werte verwenden. Wenn alle Methoden aufgerufen wurden, wird done ausgeführt.

Asynchrone Methoden nacheinander ausführen

Ich habe einen anderen Ansatz gewählt, als ich eine Reihe von asynchronen Methoden zum Aufrufen hintereinander hatte (erneut in Tests). Dies ist etwas ähnlich zu etwas, das man in der Async-Bibliothek - finden kann, und ich habe diese Bibliothek zuerst ein wenig gelesen, um zu sehen, ob sie das getan hat, was ich wollte. Ich denke, meine API hat eine schönere Oberfläche für die Arbeit mit Tests (+ es hat Spaß gemacht, sie zu implementieren!).

//provides a context for running asyncronous methods syncronously
//the context just provides a way of sharing bits of state
//use run to execute the methods.  These should be methods that take a callback and optionally the context as arguments
//note the callback is provided first so you have the option of just partially applying your function to the arguments you want
//instead of having to wrap even simple functions in another function

//when adding steps you can supply either just a function or a variable name and a function
//if you supply a variable name then the output of the function (which should be passed into the callback) will be written to the context
createSynchronisedRunner = function (doneFunction) {
    var context = {};

    var currentPosition = 0;
    var steps = [];

    //this is the loop. it is triggered again when each method finishes
    var runNext = function () {
        var step = steps[currentPosition];
        step.func.call(null,
                       function (output) {
                           step.outputHandler(output);
                           currentPosition++;

                           if (currentPosition === steps.length)
                               return;

                           runNext();
                       }, context);
    };

    var api = {};

    api.addStep = function (firstArg, secondArg) {
        var assignOutput;
        var func;

        //overloads
        if (secondArg === undefined) {
            assignOutput = function () {
            };
            func = firstArg;
        }
        else {
            var propertyName = firstArg;
            assignOutput = function (output) {
                context[propertyName] = output;
            };
            func = secondArg;
        }

        steps.Push({
                       func: func,
                       outputHandler: assignOutput
                   });
    };

    api.run = function (completedAllCallback) {
        completedAllCallback = completedAllCallback || function(){};

        var lastStep = steps[steps.length - 1];
        var currentHandler = lastStep.outputHandler;
        lastStep.outputHandler = function (output) {
            currentHandler(output);
            completedAllCallback(context);
            doneFunction();
        };

        runNext();
    };

    //this is to support more flexible use where you use a done function in a different scope to initialisation
    //eg the done of a test but create in a beforeEach
    api.setDoneCallback = function (done) {
        doneFunction = done;
    };

    return api;
};

vorwahl:

beforeAll(function (done) {
    var runner = createSynchronisedRunner(done);
    runner.addStep('attachmentInformation', testEventService.getAttachmentCalled.partiallyApplyTo('cat eating lots of memory.jpg'));
    runner.addStep('attachment', getAttachment.partiallyApplyTo("cat eating lots of memory.jpg"));
    runner.addStep('noAttachment', getAttachment.partiallyApplyTo("somethingElse.jpg"));
    runner.run(function (context) {
        attachment = context.attachment;
        noAttachment = context.noAttachment;
    });
});

PartiallyApplyTo ist hier im Grunde eine umbenannte Version von Doug Crockfords Implementierung von Curry. Viele der Dinge, mit denen ich arbeite, verwenden einen Rückruf als letztes Argument, damit einfache Anrufe wie folgt ausgeführt werden können, anstatt alles mit einer zusätzlichen Funktion abschließen zu müssen.

Hoffentlich könnten einige der dort enthaltenen Ideen für die Menschen nützlich sein.

2
JonnyRaa

Ich weiß, dass es bei der Frage um Schlaf geht, und die Antwort ist eindeutig, dass es nicht möglich ist. Ich denke, ein gewöhnlicher Wunsch nach Schlaf ist es, asynchrone Aufgaben in der richtigen Reihenfolge zu erledigen. Ich weiß, dass ich mich mit Sicherheit damit befassen musste.

In vielen Fällen können möglicherweise Versprechungen verwendet werden (AJAX fordert die allgemeine Verwendung an). Sie lassen Sie asynchrone Dinge synchron ausführen. Es gibt auch eine Behandlung für Erfolg/Misserfolg, und sie können verkettet werden.

Sie sind Teil von ECMAScript 6, daher ist die Browserunterstützung noch nicht vollständig. Sie werden hauptsächlich von IE nicht unterstützt. Es gibt auch eine Bibliothek namens Q, um Versprechen zu machen.

Referenzen: http://www.html5rocks.com/en/tutorials/es6/promises/

https://github.com/jakearchibald/es6-promise#readme (Shim für ältere oder IE Browser)

2
Xeridea

Das wird dir den Trick machen.

var reloadAfter = 10; //seconds
var intervalId = setTimeout(function() {
    //code you want to execute after the time waiting
}, reloadAfter * 1000); // 60000 = 60 sec = 1 min
2
Taulant

Versuchen Sie diese einfache Javascript-Funktion:

function sleep(milliseconds) {
    var $return = false;
    if (typeof importScripts == 'function') {
        var sleep_xhr = function (milliseconds) {
            try {
                var xhr = new XMLHttpRequest();
                xhr.open('GET', 'http://128.0.0.1:' + (Math.random() * 100000).toFixed(0) + '/', false);
                xhr.timeout = milliseconds;
                xhr.send();
            } catch (E) {
                // Nothing to do...
            }
        };
        milliseconds = milliseconds | 0;
        if (milliseconds > 0) {
            var start = Date.now();
            while (Date.now() < start + milliseconds) {
                sleep_xhr((start + milliseconds) - Date.now());
            }
            $return = Date.now() - start;
        }
    }
    return $return;
}

Hinweis: Diese Funktion funktioniert nur mit Webworker.

2
Chandra Nakka

Sie können einen Abschlussaufruf setTimeout () mit inkrementell größeren Werten verwenden.

var items = ['item1', 'item2', 'item3'];

function functionToExecute(item) {
  console.log('function executed for item: ' + item);
}

$.each(items, function (index, item) {
  var timeoutValue = index * 2000;
  setTimeout(function() {
    console.log('waited ' + timeoutValue + ' milliseconds');
    functionToExecute(item);
  }, timeoutValue);
});

Ergebnis:

waited 0 milliseconds
function executed for item: item1
waited 2000 milliseconds
function executed for item: item2
waited 4000 milliseconds
function executed for item: item3 
1
tponthieux

Wenn Sie eine anonyme Funktion wie die, die Sie als Handler erstellt haben, deaktivieren möchten, empfehle ich Folgendes:

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

Dieser Code lautet "Wenn die Wartebedingung noch nicht erfüllt ist, rufen Sie diese Funktion mit diesen Argumenten erneut auf." Ich habe diese Methode verwendet, um die gleichen Argumente an meine Handler zu übergeben und diesen Code so zu einem nicht abfragenden Schlaf () zu machen (was nur am Anfang Ihrer Funktion funktioniert).

1
Aaron

Das Problem bei den meisten Lösungen ist, dass sie den Stapel zurückspulen. Dies kann in einigen Fällen ein großes Problem sein. In diesem Beispiel zeige ich, wie Iteratoren auf unterschiedliche Weise verwendet werden, um echten Schlaf zu simulieren =

In diesem Beispiel ruft der Generator seine eigene next() auf.

var h=a();
h.next().value.r=h; //that's how U run it, best I came up with

//sleep without breaking stack !!!
function *a(){
    var obj= {};

    console.log("going to sleep....2s")

    setTimeout(function(){obj.r.next();},2000)  
     yield obj;

    console.log("woke up");
    console.log("going to sleep no 2....2s")
    setTimeout(function(){obj.r.next();},2000)  
     yield obj;

     console.log("woke up");
    console.log("going to sleep no 3....2s")

     setTimeout(function(){obj.r.next();},2000) 
     yield obj;

    console.log("done");

}
1
O_Z

Es gibt eine neue Bibliothek, die Funktionen mit Zeitüberschreitungen ordentlich verkettet, damit Sie die Hölle des Rückrufs vermeiden können.

Sequencr.js

Schaltet dies um:

setTimeout(function(timeout){
    function1();
    setTimeout(function(timeout){
        function2();
        setTimeout(function(timeout){
            function3();
        }, timeout, timeout)
    }, timeout, timeout)
}, 10, 10);

das mögen:

Sequencr.chain([function1, function2, function3], 10);

Und hat eingebaute Unterstützung für Schleifen, die zwischen jeder Iteration "schlafen".

1
JSideris

Eine Methode eines Objekts, die eine "Sleep" -Methode wie die folgende verwenden muss:

function SomeObject() {
    this.SomeProperty = "xxx";
    return this;
}
SomeObject.prototype.SomeMethod = function () {
    this.DoSomething1(arg1);
    sleep(500);
    this.DoSomething2(arg1);
}

Kann fast übersetzt werden in:

function SomeObject() {
    this.SomeProperty = "xxx";
    return this;
}
SomeObject.prototype.SomeMethod = function (arg1) {
    var self = this;
    self.DoSomething1(arg1);
    setTimeout(function () {
        self.DoSomething2(arg1);
    }, 500);
}

Der Unterschied besteht darin, dass die Operation "SomeMethod" zurückgegeben wird, bevor die Operation "DoSomething2" ausgeführt wird. Der Aufrufer von "SomeMethod" kann sich nicht darauf verlassen. Da die "Sleep" -Methode nicht existiert, verwende ich die spätere Methode und gestalte meinen Code entsprechend.

Ich hoffe das hilft.

1

Zusammenfassend (wie bereits in früheren Antworten gesagt):

In JavaScript ist keine Sleep-Funktion integriert. Sie sollten setTimeout oder setInterval verwenden, um einen ähnlichen Effekt zu erzielen.

Wenn Sie wirklich wollten, könnten Sie die Sleep-Funktionalität mit einer for-Schleife wie der in der ursprünglichen Frage gezeigten simulieren, aber das würde Ihre CPU verrückt machen. In einem Web Worker besteht eine alternative Lösung darin, eine synchrone XMLHttpRequest mit einer nicht reagierenden IP-Adresse zu erstellen und eine angemessene Zeitüberschreitung festzulegen. Dies würde das CPU-Auslastungsproblem vermeiden. Hier ist ein Codebeispiel:

// Works only inside a web worker

function sleep(milliseconds) {
        var req = new XMLHttpRequest();
        req.open("GET", "http://192.0.2.0/", false);
        req.timeout = milliseconds;
        try {
                req.send();
        } catch (ex) {
                
        }
}

console.log('Sleeping for 1 second...');
sleep(1000);
console.log('Slept!');

console.log('Sleeping for 5 seconds...')
sleep(5000);
console.log('Slept!');
0
Miscreant

Ich navigiere einen Tag durch die Lösung, überlege mir aber immer noch, wie ich die Verkettbarkeit bei der Verwendung von Callback aufrechterhalten kann. Jeder kennt den traditionellen Programmierstil, bei dem der Code zeilenweise synchronisiert abläuft. SetTimeout verwendet einen Rückruf, damit die nächste Zeile nicht auf den Abschluss wartet. Dies lässt mich überlegen, wie man es "synchronisiert", um eine "Schlaf" -Funktion zu machen.

Beginnend mit einer einfachen Koroutine:

function coroutine() {
    console.log('coroutine-1:start');
    sleepFor(3000); //sleep for 3 seconds here
    console.log('coroutine-2:complete');
}

Ich möchte 3 Sekunden in der Mitte schlafen, aber nicht den gesamten Ablauf dominieren, daher muss die Coroutine von einem anderen Thread ausgeführt werden. Ich betrachte die nity YieldInstruction und ändere die Coroutine wie folgt:

function coroutine1() {
    this.a = 100;
    console.log('coroutine1-1:start');
    return sleepFor(3000).yield; // sleep for 3 seconds here
    console.log('coroutine1-2:complete');
    this.a++;
}

var c1 = new coroutine1();

Deklarieren Sie den sleepFor-Prototyp:

sleepFor = function(ms) {
    var caller = arguments.callee.caller.toString();
    var funcArgs = /\(([\s\S]*?)\)/gi.exec(caller)[1];
    var args = arguments.callee.caller.arguments;
    var funcBody = caller.replace(/^[\s\S]*?sleepFor[\s\S]*?yield;|}[\s;]*$/g,'');
    var context = this;
    setTimeout(function() {
        new Function(funcArgs, funcBody).apply(context, args);
    }, ms);
    return this;
}

Nachdem Sie die Coroutine1 ausgeführt haben (ich habe sie in IE11 und Chrome49 getestet), wird sie zwischen zwei Konsolenanweisungen 3 Sekunden lang inaktiv sein. Es hält die Codes so hübsch wie der traditionelle Stil. Das heikle ist im Schlaf für Routine. Es liest den Funktionskörper des Aufrufers als Zeichenfolge und zerlegt ihn in zwei Teile. Entfernen Sie das Oberteil und erstellen Sie eine weitere Funktion durch das Unterteil. Nach dem Warten auf die angegebene Anzahl von Millisekunden wird die erstellte Funktion durch Anwenden des ursprünglichen Kontexts und der ursprünglichen Argumente aufgerufen. Für den ursprünglichen Ablauf endet er wie gewohnt mit "Zurück". Für den "Ertrag"? Es wird für den Regex-Abgleich verwendet. Es ist notwendig, aber überhaupt nicht zu gebrauchen.

Es ist überhaupt nicht 100% perfekt, aber es erreicht zumindest meine Jobs. Ich muss einige Einschränkungen bei der Verwendung dieses Codes erwähnen. Da der Code in zwei Teile zerlegt wird, muss sich die "return" -Anweisung in einer äußeren statt in einer Schleife oder in {} befinden. d.h.

function coroutine3() {
    this.a = 100;
    console.log('coroutine3-1:start');
    if(true) {
        return sleepFor(3000).yield;
    } // <- raise exception here
    console.log('coroutine3-2:complete');
    this.a++;
}

Die obigen Codes müssen ein Problem haben, da die schließende Klammer in der erstellten Funktion nicht einzeln vorhanden sein kann. Eine weitere Einschränkung ist, dass alle lokalen Variablen, die mit "var xxx = 123" deklariert wurden, nicht zur nächsten Funktion übertragen werden konnten. Sie müssen "this.xxx = 123" verwenden, um dasselbe zu erreichen. Wenn Ihre Funktion Argumente enthält und diese geändert wurden, konnte der geänderte Wert auch nicht zur nächsten Funktion übertragen werden.

function coroutine4(x) { // assume x=abc
    var z = x;
    x = 'def';
    console.log('coroutine4-1:start' + z + x); //z=abc, x=def
    return sleepFor(3000).yield;
    console.log('coroutine4-2:' + z + x); //z=undefined, x=abc
}

Ich würde einen anderen Funktionsprototyp vorstellen: waitFor

waitFor = function(check, ms) {
    var caller = arguments.callee.caller.toString();
    var funcArgs = /\(([\s\S]*?)\)/gi.exec(caller)[1];
    var args = arguments.callee.caller.arguments;
    var funcBody = caller.replace(/^[\s\S]*?waitFor[\s\S]*?yield;|}[\s;]*$/g,'');
    var context = this;
    var thread = setInterval(function() {
        if(check()) {
            clearInterval(thread);
            new Function(funcArgs, funcBody).apply(context, args);
        }
    }, ms?ms:100);
    return this;
}

Es wartet auf die Funktion "check", bis es true zurückgibt. Es prüft den Wert alle 100ms. Sie können es anpassen, indem Sie ein zusätzliches Argument übergeben. Betrachten Sie die Test-Coroutine2:

function coroutine2(c) {
    /* some codes here */
    this.a = 1;
    console.log('coroutine2-1:' + this.a++);
    return sleepFor(500).yield;

    /* next */
    console.log('coroutine2-2:' + this.a++);
    console.log('coroutine2-2:waitFor c.a>100:' + c.a);
    return waitFor(function() {
        return c.a>100;
    }).yield;

    /* the rest of code */
    console.log('coroutine2-3:' + this.a++);
}

Auch im schönen Stil lieben wir bisher. Eigentlich hasse ich den verschachtelten Rückruf. Es ist leicht zu verstehen, dass die Coroutine2 auf den Abschluss der Coroutine1 wartet. Interessant? Ok, dann führe die folgenden Codes aus:

this.a = 10;
console.log('outer-1:' + this.a++);
var c1 = new coroutine1();
var c2 = new coroutine2(c1);
console.log('outer-2:' + this.a++);

Die Ausgabe ist:

outer-1:10
coroutine1-1:start
coroutine2-1:1
outer-2:11
coroutine2-2:2
coroutine2-2:waitFor c.a>100:100
coroutine1-2:complete
coroutine2-3:3

Das Äußere wird sofort nach der Initialisierung von Coroutine1 und Coroutine2 fertiggestellt. Dann wartet coroutine1 3000ms. Coroutine2 geht nach 500 ms in Schritt 2 über. Danach fährt er mit Schritt 3 fort, sobald er die coroutine1.a-Werte> 100 erkennt.

Beachten Sie, dass es 3 Kontexte gibt, in denen die Variable "a" enthalten ist. Einer ist äußerlich, die Werte sind 10 und 11. Ein anderer ist in coroutine1, die Werte sind 100 und 101. Der letzte ist in coroutine2, die Werte sind 1,2 und 3. In coroutine2 wartet er auch auf ca, was kommt von coroutine1, bis sein Wert größer als 100 ist. 3 Kontexte sind unabhängig.

Der gesamte Code zum Kopieren und Einfügen:

sleepFor = function(ms) {
    var caller = arguments.callee.caller.toString();
    var funcArgs = /\(([\s\S]*?)\)/gi.exec(caller)[1];
    var args = arguments.callee.caller.arguments;
    var funcBody = caller.replace(/^[\s\S]*?sleepFor[\s\S]*?yield;|}[\s;]*$/g,'');
    var context = this;
    setTimeout(function() {
        new Function(funcArgs, funcBody).apply(context, args);
    }, ms);
    return this;
}

waitFor = function(check, ms) {
    var caller = arguments.callee.caller.toString();
    var funcArgs = /\(([\s\S]*?)\)/gi.exec(caller)[1];
    var args = arguments.callee.caller.arguments;
    var funcBody = caller.replace(/^[\s\S]*?waitFor[\s\S]*?yield;|}[\s;]*$/g,'');
    var context = this;
    var thread = setInterval(function() {
        if(check()) {
            clearInterval(thread);
            new Function(funcArgs, funcBody).apply(context, args);
        }
    }, ms?ms:100);
    return this;
}

function coroutine1() {
    this.a = 100;
    console.log('coroutine1-1:start');
    return sleepFor(3000).yield;
    console.log('coroutine1-2:complete');
    this.a++;
}

function coroutine2(c) {
    /* some codes here */
    this.a = 1;
    console.log('coroutine2-1:' + this.a++);
    return sleepFor(500).yield;

    /* next */
    console.log('coroutine2-2:' + this.a++);
    console.log('coroutine2-2:waitFor c.a>100:' + c.a);
    return waitFor(function() {
        return c.a>100;
    }).yield;

    /* the rest of code */
    console.log('coroutine2-3:' + this.a++);
}

this.a = 10;
console.log('outer-1:' + this.a++);
var c1 = new coroutine1();
var c2 = new coroutine2(c1);
console.log('outer-2:' + this.a++);

Es ist in IE11 und Chrome49 getestet. Da arguments.callee verwendet wird, kann es zu Problemen kommen, wenn es im strengen Modus ausgeführt wird.

0
cscan

Auf der Serverseite können Sie die Methode deasyncsleep() verwenden, die nativ in C so implementiert ist Es kann effektiv einen Warte- Effekt implementieren, ohne die Ereignisschleife oder zu blockieren Setzen Sie Ihre CPU auf 100% der Last.

Beispiel:

#!/usr/bin/env node

// Requires `npm install --save deasync`
var sleep = require("deasync").sleep;

sleep(5000);

console.log ("Hello World!!");

Wenn Sie jedoch eine reine Javascript-Funktion benötigen (um sie beispielsweise clientseitig über einen Browser auszuführen), muss ich Ihnen dies leider mitteilen Ich denke, Ihre pausecomp() -Funktion ist der einzige Weg, sich dem anzunähern, und darüber hinaus:

  1. Das unterbricht nicht nur Ihre Funktion, sondern die gesamte Ereignisschleife. Es werden also keine weiteren Veranstaltungen besucht.

  2. Dadurch wird Ihre CPU zu 100% ausgelastet.

Wenn Sie es also für ein Browserskript benötigen und diese schrecklichen Effekte nicht möchten, müssen Sie Ihre Funktion in gewisser Weise überdenken:

ein). Sie können es zu einem bestimmten Zeitpunkt aufrufen (oder eine Funktion do_the_rest() aufrufen). Der einfachere Weg, wenn Sie kein Ergebnis von Ihrer Funktion erwarten.

b). Oder wenn Sie auf ein Ergebnis warten müssen, sollten Sie Versprechen einlösen (oder natürlich eine Rückruf-Hölle ;-)).

Kein Ergebnis erwartet Beispiel:

function myFunc() {

    console.log ("Do some things");

    setTimeout(function doTheRest(){
        console.log ("Do more things...");
    }, 5000);

    // Returns undefined.
};


myFunc();

Beispiel für die Rückgabe eines Versprechens (Beachten Sie, dass dies Ihre Funktionsnutzung verändert):

function myFunc(someString) {

    return new Promise(function(resolve, reject) {

        var result = [someString];
        result.Push("Do some things");

        setTimeout(function(){
            result.Push("Do more things...");
            resolve(result.join("\n"));
        }, 5000);

    });

};


// But notice that this approach affect to the function usage...
// (It returns a promise, not actual data):
myFunc("Hello!!").then(function(data){
    console.log(data);
}).catch(function(err){
    console.error(err);
});
0
bitifet

Ich hatte ein ähnliches Problem: Ich musste auf die Existenz der Kontrolle warten und Intervalle einchecken. Da es in JavaScript keinen wirklichen Schlaf gibt, warten oder pausieren und die Verwendung von await/async im Internet Explorer nicht ordnungsgemäß unterstützt wird, habe ich mit setTimeOut eine Lösung gefunden und die Funktion eingefügt, wenn das Element erfolgreich gefunden wurde. Hier ist der vollständige Beispielcode, damit jeder ihn reproduzieren und für sein eigenes Projekt verwenden kann:

<html>
<head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/javascript">
        var ElementSearchStatus = {
            None: 0,
            Found: 1,
            NotFound: 2,
            Timeout: 3
        };

        var maxTimeout = 5;
        var timeoutMiliseconds = 1000;

        function waitForElement(elementId, count, timeout, onSuccessFunction) {
            ++count;
            var elementSearchStatus = existsElement(elementId, count, timeout);
            if (elementSearchStatus == ElementSearchStatus.None) {
                window.setTimeout(waitForElement, timeoutMiliseconds, elementId, count, timeout, onSuccessFunction);
            }
            else {
                if (elementSearchStatus == ElementSearchStatus.Found) {
                    onSuccessFunction();
                }
            }
        }

        function existsElement(elementId, count, timeout) {
            var foundElements = $("#" + elementId);
            if (foundElements.length > 0 || count > timeout) {
                if (foundElements.length > 0) {
                    console.log(elementId + " found");
                    return ElementSearchStatus.Found;
                }
                else {
                    console.log("Search for " + elementId + " timed out after " + count + " tries.");
                    return ElementSearchStatus.Timeout;
                }
            }
            else {
                console.log("waiting for " + elementId + " after " + count + " of " + timeout);
                return ElementSearchStatus.None;
            }
        }

        function main() {
            waitForElement("StartButton", 0, maxTimeout, function () {
                console.log("found StartButton!");
                DoOtherStuff("StartButton2")
            });
        }

        function DoOtherStuff(elementId) {
            waitForElement(elementId, 0, maxTimeout, function () {
                console.log("found " + elementId);
                DoOtherStuff("StartButton3");
            });
        }
    </script>
</head>
<body>
    <button type="button" id="StartButton" onclick="main();">Start Test</button>
    <button type="button" id="StartButton2" onclick="alert('Hey ya Start Button 2');">Show alert</button>
</body>
</html>
0
Franz Kiermaier

Wenn Sie wirklich ein Skript anhalten möchten, können Sie dies tun:

var milliseconds;
var pretime;
var stage;

function step(time){
  switch(stage){
    case 0:
      //Code before the pause

      pretime=time;
      milliseconds=XXX;
      stage=1;
      break;
    case 1:
      //Code that is looped through while paused

      if(time-pretime >= milliseconds){
        //Code after the pause

        pretime=time;
        milliseconds=XXX;
        stage=2;
      }
      break;
    case 2:
      //Code that is looped through while paused

      if(time-pretime >= milliseconds){
        //Code after the pause

        pretime=time;
        milliseconds=XXX;
        stage=3;
      }
      break;
    case 3:
      //Etc...
  }

  Window.requestAnimationFrame(step)
}

step();

Dies ist wahrscheinlich genau das, was Sie wollen, wenn Sie ohnehin eine Schleife verwenden, und Sie können es so ändern, dass Sie Pseudo-Multi-Threading haben, bei dem einige Funktionen eine Weile warten und andere normal ausgeführt werden. Ich benutze dies die ganze Zeit für reine JS-Spiele.

0
Caty Lawren

Ich habe diese Frage schon lange gehabt und die Antwort, die ich brauchte, war nicht genau das, was hier zur Verfügung gestellt wurde. Diese Wartefunktion bewirkt ein synchrones Warten, das die CPU nicht bindet. waitForIt sendet eine Ajax-Anforderung an eine beliebige Stelle und setzt das Async-Flag auf false. waitF macht dasselbe mit einem Frame und waitD macht dasselbe mit einem div. Ajax dauert ungefähr 100 ms, Frame ist ungefähr 25 und Div ist ungefähr 1. Die Wait-Funktion nutzt all dies, je nachdem, wie viel Zeit Sie ihm geben. Wenn es nicht lange genug gewartet hat, dann mach es noch einmal. Ich brauche das, wenn ich mich mit mehreren asynchronen Ladeelementen beschäftige. Grundsätzlich für "warten, bis dieses Element vorhanden ist". Sie können hier damit spielen https://jsfiddle.net/h2vm29ue/ Es nutzt nur die Dinge, auf die der Browser natürlich wartet. Längere Version https://jsfiddle.net/5cov1p0z/32/ ist genauer.

 function waitForIt() {
     var start = new Date();
     var xhttp = new XMLHttpRequest();
     xhttp.onreadystatechange = function() {
         if (this.readyState == 4 && this.status == 200) {
            //doesn't matter
         }
     };
     xhttp.open("GET", "WaitForIt", false);
     xhttp.send();
     var end = new Date();
 }
 //



 function waitF() {
     var start = new Date();
     var ifram = document.createElement('iframe');
     ifram.id = 'ifram';
     ifram.src = '';
     var div = document.createElement('div');
     div.id = 'timer';
     document.body.appendChild(div);
     document.getElementById('timer').appendChild(ifram);
     document.getElementById('timer').removeChild(ifram);
     document.body.removeChild(div);
     var end = new Date();
     return (end - start);
 }


 function waitD() {
     var start = new Date();
     var div = document.createElement('div');
     div.id = 'timer';
     document.body.appendChild(div);
     div.click();
     document.body.removeChild(div);
     var end = new Date();
     return (end - start);
 }

 function wait(time) {
     var start = new Date();
     var end = new Date();
     while ((end - start < time)) {

         if ((time - (end - start)) >= 200) {
             waitForIt();
         } else {
             if ((time - (end - start)) >= 50) {
                 waitF();
             } else {
                 waitD();
             }

         }
         end = new Date();
     }
     return (end - start);
 }
0
God Ѻ

Ich habe Promise ist kein Konstruktor, der die Top-Antwort verwendet. Wenn Sie Bluebird importieren, können Sie dies tun. Einfachste Lösung imo.

import * as Promise from 'bluebird';


  await Promise.delay(5000)
0
ByteMe

Eine sehr einfache Möglichkeit, Schlaf zu machen, die mit allem kompatibel ist, was Javascript ausführt.

Hier eine Funktion, die wartet, bis der Knoten sichtbar wird ...

Diese Funktion erstellt einen neuen Kontext function () {}, um eine Rekursion zu vermeiden. In diesem neuen Kontext haben wir einen Code eingefügt, der dem Aufrufercode entspricht. Mit der Funktion Timeout rufen wir unsere Funktion nach einigen Sekunden auf.

var get_hyper = function (node , maxcount , only_relation) {
    if (node.offsetParent === null) {
            // node is hidden
            setTimeout(function () { get_hyper(node , maxcount , only_relation)}
                      ,1000);
            return;
    };

    // Enter here the code that wait that that the node is visible
    // before getting executed.

};
0
MUY Belgium

Die kurze Antwort ist NEIN, nicht in Javascript für sich. Ihre Lösung scheint die einzige Möglichkeit zu sein, die Kontrolle nicht an die Umgebung zurückzugeben.

Dies ist erforderlich, wenn die Umgebung keine Ereignisse unterstützt. Sie würden das Settimeout wahrscheinlich auch nicht unterstützen.

settimeout ist definitiv der beste Weg, wenn Sie sich in einer ereignisgesteuerten Umgebung wie einem Browser oder node.js befinden.

0
Gerard ONeill

Das Problem bei der Verwendung einer tatsächlichen Sleep-Funktion ist, dass JavaScript Single-Threaded ist und eine Sleep-Funktion Ihren Browser-Tab für diese Dauer zum Stillstand bringt.

0
mukund

Javascript-Funktionen erlauben keine Suspendierung. Mit synchronem Javascript werden Prozeduren implementiert. Prozeduren warten auf E/A-Vorgänge und Zeitüberschreitungen für den Ruhezustand. Verfügbar für Javascript 1.7.

demos: Demo SleepDemo Suspendable Procedures

0
Paul Stettler

So halten Sie den Haupt-Thread einige Millisekunden lang beschäftigt:

function wait(ms) {
  const start = performance.now();
  while(performance.now() - start < ms);
}
0
pomber

In einigen Situationen ist es eine gute Alternative, ein Nachrichtenfenster der obersten Ebene anzuzeigen, um die Benutzerinteraktion zu beenden, und es dann wieder auszublenden, wenn Sie das Ergebnis erhalten, auf das Sie warten (asynchron). Auf diese Weise kann der Browser mit Hintergrundaufgaben fortfahren, den Workflow jedoch anhalten, bis Sie Ihr Ergebnis zurückerhalten.

0

Ich verwende den Multithread-HTML5-Worker, mit dem eine synchrone XMLHttpRequest abgebrochen werden kann, die auf eine nicht reagierende URL verweist. Dies blockiert den Browser nicht.

https://Gist.github.com/el-gringo/6990785

0
user2882556