Question Quelle est la version JavaScript de sleep ()?


Y a-t-il une meilleure façon d'élaborer un sleep en JavaScript que ce qui suit pausecomp fonction (pris d'ici)?

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

Ce n'est pas un duplicata de Sleep in JavaScript - délai entre les actions; je veux un vrai sommeil au milieu d'une fonction, et non un délai avant l'exécution d'un morceau de code.


1519
2017-10-07 09:44


origine


Réponses:


Mise à jour 2017

Depuis 2009, lorsque cette question a été posée, JavaScript a considérablement évolué. Toutes les autres réponses sont maintenant obsolètes ou trop compliquées. Voici la meilleure pratique actuelle:

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

Ça y est. await sleep(<duration>).

Vous pouvez essayer ce code en direct sur Runkit. Notez que,

  1. await ne peut être exécuté que dans les fonctions précédées du async mot-clé. Runkit encapsule votre code dans une fonction asynchrone avant de l'exécuter.
  2. await ne fait que mettre en pause le courant async fonction

Deux nouvelles fonctionnalités JavaScript ont aidé à écrire cette fonction "sleep":

Compatibilité

Si, pour une raison ou une autre, vous utilisez un nœud antérieur à 7 ou si vous ciblez d'anciens navigateurs, async/await peut encore être utilisé via Babel (un outil qui va transpile JavaScript + nouvelles fonctionnalités en JavaScript ancien), avec le transform-async-to-generator brancher. Courir

npm install babel-cli --save

Créer .babelrc avec:

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

Ensuite, exécutez votre code avec

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

Mais encore une fois, vous n'en avez pas besoin si vous utilisez Node 7 ou plus tard, ou si vous ciblez des navigateurs modernes.


1071



(Voir le réponse mise à jour pour 2016)

Je pense qu'il est parfaitement raisonnable de vouloir effectuer une action, attendre, puis effectuer une autre action. Si vous avez l'habitude d'écrire dans des langages multithread, vous avez probablement l'idée d'abandonner l'exécution pendant un certain temps jusqu'à ce que votre thread se réveille.

Le problème ici est que JavaScript est un modèle basé sur un événement à un seul thread. Dans un cas spécifique, il peut être intéressant d'attendre quelques secondes avant que le moteur ne soit en panne, en général c'est une mauvaise pratique. Supposons que je veuille utiliser vos fonctions en écrivant les miennes? Quand j'ai appelé votre méthode, mes méthodes gèlent toutes. Si JavaScript pouvait en quelque sorte préserver le contexte d'exécution de votre fonction, le stocker quelque part, puis le ramener et le continuer plus tard, alors le sommeil pourrait se produire, mais ce serait essentiellement le threading.

Vous êtes donc plutôt bloqué avec ce que d'autres ont suggéré - vous devrez casser votre code en plusieurs fonctions.

Votre question est un peu un faux choix, alors. Il n'y a aucun moyen de dormir comme vous le souhaitez, ni de poursuivre la solution que vous suggérez.


830



En JavaScript, je réécris chaque fonction pour qu'elle puisse se terminer le plus rapidement possible. Vous voulez que le navigateur retrouve le contrôle afin qu'il puisse modifier votre DOM.

Chaque fois que j'ai voulu dormir au milieu de ma fonction, j'ai refacturé d'utiliser un setTimeout().

Je vais éditer cette réponse parce que j'ai trouvé cela utile:

Le sommeil infâme, ou retard, fonction dans n'importe quelle langue est beaucoup débattu. Certains diront qu'il devrait toujours y avoir un signal ou rappel pour déclencher une fonctionnalité donnée, d'autres diront que parfois un moment de retard arbitraire est utile. Je dis que chacun à leur propre et une règle ne peut jamais rien dicter dans cette industrie.

L'écriture d'une fonction de sommeil est simple et rendue encore plus utilisable avec JavaScript Promises:

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

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

590



Seulement pour déboguer / dev , Je poste ça si c'est utile à quelqu'un

Chose intéressante, dans Firebug (et probablement d'autres consoles js), rien ne se passe après avoir tapé, seulement après la durée de sommeil spécifiée (...)

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

Exemple d'utilisation:

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

269



Je suis d'accord avec les autres affiches, un sommeil occupé est juste une mauvaise idée.

Cependant, setTimeout ne retarde pas l'exécution, il exécute la ligne suivante de la fonction immédiatement après que le délai d'attente est réglé sur SET, et non après l'expiration du délai, ce qui n'effectue pas la même tâche qu'un sommeil.

La façon de le faire est de décomposer votre fonction en avant et après les parties.

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

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

Assurez-vous que les noms de vos fonctions décrivent toujours exactement ce que fait chaque pièce (I.E. GatherInputThenWait et CheckInput, plutôt que funcPart1 et funcPart2)

modifier 

Cette méthode a pour but de ne pas exécuter les lignes de code que vous décidez APRES votre expiration, tout en retournant le contrôle au PC client pour exécuter tout ce qu'il a mis en file d'attente.

Modifier plus loin

Comme indiqué dans les commentaires cela ne fonctionnera absolument pas en boucle. Vous pourriez faire un peu de hacking (moche) de fantaisie pour le faire fonctionner en boucle, mais en général cela fera juste pour le code de spaghetti désastreux.


164



Pour l'amour de $ DEITY s'il vous plaît ne faites pas une fonction de sommeil occupé-wait. setTimeout et setInterval fais tout ce dont tu as besoin.


113



Je sais que c'est un peu une vieille question, mais si (comme moi) vous utilisez Javascript avec Rhino, vous pouvez utiliser ...

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