3676 votes

Quelle est la version JavaScript de sleep() ?

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

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

Il ne s'agit pas d'un duplicata de Sleep en JavaScript - délai entre les actions ; je veux un le vrai sommeil au milieu d'une fonction, et non un délai avant l'exécution d'un morceau de code.

6 votes

C'est à placer au milieu d'un while, si j'utilise setTimeout, le while continuera à traiter et à mettre en file d'attente d'autres setTimeout qui finiront par s'exécuter en même temps et par créer un peu de concurrence entre eux.

210 votes

C'est une solution horrible - vous allez mâcher des cycles de traitement tout en ne faisant rien.

14 votes

La seule raison d'être d'un sleep est d'interroger ou d'attendre un callback - setInterval et setTimeout font mieux que cela.

867voto

Ben Flynn Points 5346

(Voir le réponse actualisée 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 multithreads, vous avez probablement l'idée de céder l'exécution pendant une durée déterminée jusqu'à ce que votre thread se réveille.

Le problème ici est que JavaScript est un modèle basé sur les événements à un seul thread. Bien que dans un cas spécifique, il puisse être agréable de faire attendre le moteur entier pendant quelques secondes, en général, c'est une mauvaise pratique. Supposons que je veuille utiliser vos fonctions tout en écrivant les miennes ? Lorsque j'appelle votre méthode, mes méthodes se figent toutes. Si JavaScript pouvait d'une manière ou d'une autre préserver le contexte d'exécution de votre fonction, le stocker quelque part, puis le ramener et continuer plus tard, alors le sommeil pourrait se produire, mais ce serait fondamentalement du threading.

Vous devez donc vous contenter de ce que d'autres ont suggéré - vous devrez décomposer votre code en plusieurs fonctions.

Votre question est un peu un faux choix, alors. Il n'y a aucun moyen de dormir de la façon dont vous le souhaitez, et vous ne devriez pas non plus poursuivre la solution que vous suggérez.

68 votes

Ce n'est pas du tout une réponse correcte. Si Javascript n'a pas de fonction sleep, c'est uniquement parce que l'ECMAScript ne l'exige pas. C'est un choix de conception de l'organisme responsable de la conception de Javascript. On aurait pu faire en sorte que le temps d'exécution de Javascript attende un temps donné avant d'exécuter la ligne de code suivante, mais on a choisi de ne pas le faire.

5 votes

Un sommeil peut parfaitement être implémenté en JavaScript, mais pas avec une précision en temps réel. Après tout, il s'agit d'un système basé sur des événements. Si les appels asynchrones sont terminés, un événement est déclenché. Je ne vois pas pourquoi la même chose ne pourrait pas être possible lorsqu'un sleep() est émis, après quoi le contrôle est renvoyé au navigateur jusqu'à ce que le sommeil soit terminé, renvoyant le contrôle à la fonction appelante. Et oui, je suis également d'accord pour dire que parfois, dormir est pratique, surtout lorsque les développeurs AVANT vous ont si mal conçu que VOUS n'avez pas d'autre solution que de refactorer complètement, ce pour quoi vous n'avez pas le temps

0 votes

Essayez Hypnotic, qui suit cette idée : coolwanglu.github.io/hypnotic/web/demo.html

796voto

Nosredna Points 33670

En JavaScript, je réécris chaque fonction pour qu'elle puisse se terminer le plus tôt possible. Vous voulez que le navigateur reprenne le contrôle afin qu'il puisse effectuer vos modifications DOM.

Chaque fois que j'ai voulu une mise en sommeil au milieu de ma fonction, j'ai refacturé pour utiliser une fonction setTimeout() .

Modifier

La fameuse fonction de sommeil, ou de retard, dans une langue est très discutée. Certains diront qu'il devrait toujours y avoir un signal ou un callback pour déclencher une fonctionnalité donnée, d'autres soutiendront que parfois un moment arbitraire de retard est utile. Je dis qu'à chacun son métier et qu'une règle ne peut jamais dicter quoi que ce soit dans ce secteur.

L'écriture d'une fonction de sommeil est simple et rendue encore plus utilisable grâce aux Promesses JavaScript :

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

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

1 votes

Cette solution ne fonctionne pas si vous avez des variables d'état. Si la fonction que vous essayez d'endormir a des paramètres. Par exemple, comment peut-on faire la fonction foobar(el){ setTimeout(foobar_cont(el),5000) ; } ? ?? Je n'ai pas encore trouvé la solution.

201 votes

En guise de clôture. function foobar(el) { setTimeout(function() { foobar_cont(el); }, 5000); }

77 votes

Ok, et si le code n'est pas destiné à être utilisé dans une page web ?

346voto

StephaneAG Points 37

En Firebug (et probablement d'autres consoles JavaScript), rien ne se passe après avoir appuyé sur la touche "entrée", 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 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: Uniquement pour le débogage et le développement

55 votes

Ce n'est pas une réponse. C'est exactement le même code que celui de la question, mais un peu plus court.

0 votes

32 votes

Occupé à attendre, vraiment ? En JS ? Pendant des secondes ? Si je surprends un site web qui fait ça, il sera bloqué.

202voto

DevinB Points 5960

Je suis d'accord avec les autres posters, une longue nuit de sommeil est une mauvaise idée.

Cependant, setTimeout ne résiste pas à l'exécution, il exécute la ligne suivante de la fonction immédiatement après le délai d'attente est DÉFINI, et non pas après l'expiration de ce délai, de sorte que de ne pas accomplir la même tâche que le sommeil allait accomplir.

La façon de le faire est de ventilation de votre fonction 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 vos noms de fonction encore décrire avec précision ce que chaque morceau est en train de faire (I. E. GatherInputThenWait et CheckInput, plutôt que de funcPart1 et funcPart2)

Modifier

Cette méthode permet d'atteindre le but de ne pas exécuter les lignes de code que vous décidez qu'APRÈS un délai d'attente, tout en continuant de rendre le contrôle au client PC pour exécuter tout ce qu'elle a mis en file d'attente.

Modifier

Comme l'a souligné dans les commentaires ce sera absolument PAS TRAVAILLER dans une boucle. Vous pourriez faire un peu de fantaisie (moche) de piratage pour le faire fonctionner dans une boucle, mais en général, qui va juste faire désastreuses de code spaghetti.

173voto

chaos Points 69029

S’il vous plaît, ne faites pas une fonction sommeil occupé-wait. et tout ce que vous devez faire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X