Vraag Wat is de JavaScript-versie van slaap ()?


Is er een betere manier om een ​​te engineeren? sleep in JavaScript dan het volgende pausecomp functie (genomen vanaf hier)?

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

Dit is geen duplicaat van Slaap in JavaScript - vertraging tussen acties; ik wil een echte slaap in het midden van een functie, en niet een vertraging voordat een stuk code wordt uitgevoerd.


1519
2017-10-07 09:44


oorsprong


antwoorden:


2017 update

Sinds 2009, toen deze vraag werd gesteld, is JavaScript aanzienlijk geëvolueerd. Alle andere antwoorden zijn nu verouderd of te gecompliceerd. Dit is de huidige beste praktijk:

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();

Dit is het. await sleep(<duration>).

Je kunt deze code live proberen op Runkit. Let daar op,

  1. await kan alleen worden uitgevoerd in functies voorafgegaan door de async trefwoord. Runkit wikkelt uw code in een asynchroonfunctie voordat deze wordt uitgevoerd.
  2. await pauzeert alleen de stroom async functie

Twee nieuwe JavaScript-functies hielpen bij het schrijven van deze actuele slaapfunctie:

Verenigbaarheid

Als u om welke reden dan ook een Node ouder dan 7 gebruikt, of als u zich richt op oude browsers, async/await kan nog steeds worden gebruikt via Babel (een tool die dat wel zal doen transpile JavaScript + nieuwe functies in gewoon oud JavaScript), met de transform-async-to-generator inpluggen. Rennen

npm install babel-cli --save

creëren .babelrc met:

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

Voer vervolgens uw code uit

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

Maar nogmaals, u hebt dit niet nodig als u Knooppunt 7 of hoger gebruikt, of als u op moderne browsers bent gericht.


1071



(Zie de bijgewerkt antwoord voor 2016)

Ik denk dat het volkomen redelijk is om een ​​actie uit te voeren, te wachten en vervolgens nog een actie uit te voeren. Als je gewend bent om in talen met meerdere threads te schrijven, heb je waarschijnlijk het idee om een ​​bepaalde tijd uitvoering te geven totdat je draad wakker wordt.

Het probleem hier is dat JavaScript een eventgebaseerd model met één thread is. In een specifiek geval is het misschien leuk om de hele motor een paar seconden te laten wachten, over het algemeen is het een slechte oefening. Stel dat ik je functies wilde gebruiken tijdens het schrijven van de mijne? Toen ik je methode opriep, vroren mijn methoden vast. Als JavaScript de uitvoeringscontext van je functie op de een of andere manier zou kunnen behouden, bewaar het dan ergens, breng het dan terug en ga later verder, dan zou er slaap kunnen gebeuren, maar dat zou in feite threading zijn.

Dus je zit vrijwel vast aan wat anderen hebben voorgesteld - je zult je code moeten opsplitsen in meerdere functies.

Uw vraag is dan een beetje een verkeerde keuze. Er is geen manier om te slapen zoals u dat wilt, en u moet ook niet doorgaan met de oplossing die u voorstelt.


830



In JavaScript herschrijf ik elke functie zodat deze zo snel mogelijk kan worden beëindigd. U wilt dat de browser weer controle krijgt, zodat uw DOM kan veranderen.

Telkens als ik een slaap in het midden van mijn functie wilde, refactored ik om a te gebruiken setTimeout().

Ik ga dit antwoord bewerken omdat ik dit nuttig vond:

De beruchte slaap of vertraging, functie in elke taal wordt veel besproken. Sommigen zullen zeggen dat er altijd een signaal of callback moet zijn om een ​​bepaalde functionaliteit te activeren, anderen zullen beweren dat soms een willekeurig moment van vertraging nuttig is. Ik zeg dat voor elk hun eigen en één regel nooit iets in deze industrie kan dicteren.

Een slaapfunctie schrijven is eenvoudig en nog beter bruikbaar met JavaScript-beloften:

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

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

590



Alleen voor debug / dev , Ik post dit als het nuttig is voor iemand

Interessante dingen, in Firebug (en waarschijnlijk andere js-consoles), gebeurt er niets na het raken van Enter, maar pas na de gespecificeerde slaapduur (...)

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

Voorbeeld van gebruik:

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

269



Ik ben het eens met de andere posters, een drukke slaap is gewoon een slecht idee.

SetTimeout houdt de uitvoering echter niet tegen, het voert de volgende regel van de functie uit onmiddellijk nadat de time-out is ingesteld, niet nadat de time-out is verstreken, dus dat heeft niet dezelfde taak als een slaap volbracht.

De manier om dit te doen is om je functie in delen voor en na te splitsen.

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

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

Zorg ervoor dat je functienamen nog steeds nauwkeurig beschrijven wat elk stuk aan het doen is (I.E. GatherInputThenWait en CheckInput, in plaats van funcPart1 en funcPart2)

Bewerk 

Met deze methode wordt het doel bereikt om de coderegels die u beslist tot NA uw time-out niet uit te voeren, terwijl u de besturing weer terugzet naar de client-pc om al het andere uit te voeren dat in de wachtrij staat.

Verdere bewerking

Zoals opgemerkt in de commentaren zal dit absoluut NIET werken. Je zou een paar fancy (lelijke) hacks kunnen doen om het in een lus te laten werken, maar in het algemeen zal dat gewoon rampzalige spaghetti-code opleveren.


164



Voor de liefde van $ DEITY, maak alsjeblieft geen drukke-wacht-slaap-functie. setTimeout en setInterval doe alles wat je nodig hebt.


113



Ik weet dat dit een oude vraag is, maar als (zoals ik) Javascript met Rhino wordt gebruikt, kun je ...

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



Als je jQuery gebruikt, heeft iemand eigenlijk een "delay" -plug-in gemaakt die niets meer is dan een wrapper voor setTimeout:

// 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;
};

U kunt het dan gewoon in een rij functieaanroepen gebruiken zoals verwacht:

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

65