Existe-t-il un meilleur moyen de créer un sleep
fichier JavaScript que la pausecomp
fonction suivante ( prise ici )?
function pausecomp(millis)
{
var date = new Date();
var curDate = null;
do { curDate = new Date(); }
while(curDate-date < millis);
}
Ce n'est pas un doublon de Sleep in JavaScript - délai entre les actions ; Je veux un vrai sommeil au milieu d'une fonction, et non pas un délai avant qu'un morceau de code ne s'exécute.
javascript
sleep
fmsf
la source
la source
Réponses:
Mise à jour 2017-2019
Depuis 2009, date à laquelle cette question a été posée, JavaScript a considérablement évolué. Toutes les autres réponses sont désormais obsolètes ou trop compliquées. Voici la meilleure pratique actuelle:
Ça y est.
await sleep(<duration>)
.Ou en monoplace:
Notez que,
await
ne peut être exécuté que dans des fonctions préfixées par leasync
mot - clé, ou au niveau supérieur de votre script dans certains environnements (par exemple la console Chrome DevTools ou Runkit).await
suspend uniquement laasync
fonction actuelleDeux nouvelles fonctionnalités JavaScript ont aidé à écrire cette fonction "veille":
async/await
fonctionnalité permet au code d'attendre explicitement qu'une promesse soit réglée (résolue ou rejetée).Compatibilité
async
/ aawait
atterri dans V8 et est activé par défaut depuis Chrome 55 (sorti en décembre 2016)Si, pour une raison étrange, vous utilisez Node plus de 7 (qui a atteint la fin de sa vie ), ou ciblez d'anciens navigateurs,
async
/await
peut toujours être utilisé via Babel (un outil qui transposera JavaScript + de nouvelles fonctionnalités en ancien JavaScript). , avec letransform-async-to-generator
plugin.la source
(Voir la 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 multithreads, vous avez probablement l'idée de céder 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 des événements à un seul thread. Alors que dans un cas spécifique, il peut être agréable de laisser le moteur entier attendre 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'appelais votre méthode, mes méthodes se bloquaient 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 continuer plus tard, alors le sommeil pourrait se produire, mais ce serait essentiellement du filetage.
Donc, vous êtes à peu près coincé avec ce que d'autres ont suggéré - vous devrez diviser votre code en plusieurs fonctions.
Votre question est donc un peu un faux choix. Il n'y a aucun moyen de dormir comme vous le souhaitez et vous ne devez pas non plus poursuivre la solution que vous proposez.
la source
sleep()
n'est pas possible dans JS, et que la plupart du temps il y a de meilleures façons de faire les choses. Mais je considérerais toujours la façon dont le moteur lie toutes choses comme un défaut de conception; il n'y a aucune raison que la langue ne puisse pas avoir unesleep()
fonction limitée à un script, une page ou une fonction spécifique sans que le moteur n'encombre le CPU et ne gèle l'application comme un maniaque. Nous sommes en 2015 et vous ne devriez pas pouvoir planter un navigateur Web entier avecwhile(1)
. Nous avons Flash pour des choses comme ça.En JavaScript, je réécris chaque fonction pour qu'elle se termine le plus rapidement possible. Vous voulez que le navigateur reprenne le contrôle afin qu'il puisse apporter vos modifications DOM.
Chaque fois que je voulais dormir au milieu de ma fonction, je refactorisais d'utiliser un
setTimeout()
.Éditer
La fameuse fonction de sommeil ou de retard dans n'importe quelle langue est très controversée. Certains diront qu'il devrait toujours y avoir un signal ou un rappel pour déclencher une fonctionnalité donnée, d'autres diront que parfois un moment de retard arbitraire est utile. Je dis qu'à chacun sa règle et qu'une règle ne peut jamais dicter quoi que ce soit dans cette industrie.
L'écriture d'une fonction de veille est simple et encore plus utilisable avec JavaScript Promises:
la source
function foobar(el) { setTimeout(function() { foobar_cont(el); }, 5000); }
Uniquement pour debug / dev , je poste ceci si c'est utile à quelqu'un
Des choses intéressantes, dans Firebug (et probablement d'autres consoles js), rien ne se passe après avoir appuyé sur enter, seulement après la durée de sommeil spécifiée (...)
Exemple d'utilisation:
la source
only for debug/dev
... rolleyesJe suis d'accord avec les autres affiches, un sommeil occupé n'est qu'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'expiration est défini, pas après l'expiration du délai d'expiration, de sorte que n'accomplit pas la même tâche qu'un sommeil accomplirait.
La façon de le faire est de décomposer votre fonction en parties avant et après.
Assurez-vous que les noms de vos fonctions décrivent toujours avec précision ce que fait chaque élément (IE GatherInputThenWait et CheckInput, plutôt que funcPart1 et funcPart2)
Éditer
Cette méthode atteint l'objectif de ne pas exécuter les lignes de code que vous décidez jusqu'à APRÈS votre délai d'expiration, tout en renvoyant le contrôle au PC client pour exécuter tout ce qu'il a mis en file d'attente.
Modifier davantage
Comme indiqué dans les commentaires, cela ne fonctionnera absolument PAS en boucle. Vous pouvez faire un piratage sophistiqué (moche) pour le faire fonctionner en boucle, mais en général, cela ne fera que créer un code de spaghetti désastreux.
la source
function foo(index) { setTimeout(function() { foo_continue(index); }, 10000); }
etfor(var X = 0; X < 3;X++) { foo(X); }
- la valeur de X est passée dansfoo
, qui est ensuite réutilisée sous le nomindex
lorsqu'ellefoo_continue
est finalement appelée.console.log()
intérieurfoo_continue()
dans la version setTimeout et vous obtenez le même résultat.Pour l'amour de $ DEITY, ne faites pas de fonction de veille d'attente.
setTimeout
etsetInterval
faites tout ce dont vous avez besoin.Toutes les deux secondes, masquez le texte pendant une seconde. Cela montre comment utiliser setInterval et setTimeout pour afficher et masquer le texte chaque seconde.
la source
Je sais que c'est un peu une vieille question, mais si (comme moi) vous utilisez Javascript avec Rhino, vous pouvez utiliser ...
la source
Si vous utilisez jQuery, quelqu'un a en fait créé un plugin "delay" qui n'est rien de plus qu'un wrapper pour setTimeout:
Vous pouvez ensuite simplement l'utiliser dans une ligne d'appels de fonction comme prévu:
la source
.delay()
fait partie de jQuery (mais avec une sémantique différente de l'implémentation ci-dessus). api.jquery.com/delayJ'ai également cherché une solution de sommeil (pas pour le code de production, seulement pour les dev / tests) et j'ai trouvé cet article:
http://narayanraman.blogspot.com/2005/12/javascript-sleep-or-wait.html
... et voici un autre lien avec les solutions côté client: http://www.devcheater.com/
De plus, lorsque vous appelez
alert()
, votre code sera également mis en pause, tandis que l'alerte est affichée - vous devez trouver un moyen de ne pas afficher l'alerte mais d'obtenir le même effet. :)la source
Voici une solution simple utilisant un XMLHttpRequest synchrone:
contenu de sleep.php:
Maintenant, appelez-le avec: sommeil (5);
la source
setTimeout()
si cela fonctionne, mais si cela signifie que vous démêlez 1000 lignes de rappels, cela pourrait ne plus ressembler à une blague.sleep(300)
et que le site Web prend 150 ms pour répondre, le code javascript sera en veille pendant 450 ms. et si la connexion Internet est perdue par le navigateur, cela ne fonctionnera que pendant 0 ms. Ce n'est donc pas une meilleure solutionVoici. Comme le dit le code, ne soyez pas un mauvais développeur et utilisez-le sur des sites Web. C'est une fonction utilitaire de développement.
la source
async/await
elle ne répond malheureusement pas, et nous devons l'utiliser de manière obligatoire.Personnellement, j'aime le simple:
puis:
Je l'utilise tout le temps pour créer de faux temps de chargement lors de la création de scripts dans P5js
la source
Première:
Définissez une fonction que vous souhaitez exécuter comme ceci:
Planifiez ensuite son exécution avec la méthode setTimeout:
Notez deux choses
la source
assurez-vous que votre fonction d'appel est asynchrone
vérifié et fonctionne bien
la source
La meilleure solution pour que les choses ressemblent à ce que la plupart des gens veulent est d'utiliser une fonction anonyme:
C'est probablement le plus proche de quelque chose qui fait simplement ce que vous voulez.
Notez que si vous avez besoin de plusieurs sommeil, cela peut devenir très vite pressé et vous devrez peut-être repenser votre conception.
la source
Pour les navigateurs, je conviens que setTimeout et setInterval sont la voie à suivre.
Mais pour le code côté serveur, il peut nécessiter une fonction de blocage (par exemple, afin que vous puissiez effectivement avoir la synchronisation des threads).
Si vous utilisez node.js et meteor, vous pouvez avoir rencontré les limites de l'utilisation de setTimeout dans une fibre. Voici le code de mise en veille côté serveur.
Voir: https://github.com/laverdet/node-fibers#sleep
la source
Server may require a blocking function
... Je ne vois pas à quel point bloquer avec force le seul thread de Node et rendre votre serveur entier sans réponse pendant plusieurs secondes est une bonne idée, mais peu importeJ'encapsulerais setTimeOut dans une promesse de cohérence du code avec d'autres tâches asynchrones: Démo dans Fiddle
Utilisé comme ça:
Il est facile de se souvenir de la syntaxe si vous utilisiez auparavant Promises.
la source
Mise à jour 2019 à l'aide d' Atomics.wait
Devrait fonctionner dans le nœud 9.3 ou supérieur.
J'avais besoin d'une minuterie assez précise dans Node.js et cela fonctionne très bien pour cela. Cependant, il semble que le support des navigateurs soit extrêmement limité.
A exécuté quelques repères de minuterie de 10 secondes.
Avec setTimeout, j'obtiens une erreur allant jusqu'à 7000 microsecondes. (7 ms)
Avec Atomics, mon erreur semble rester inférieure à 600 microsecondes. (0,6 ms)
Mise à jour 2020: en résumé
dont la page côté serveur, par exemple
sleep.jsp
, ressemble àla source
La plupart des réponses ici sont erronées ou pour le moins dépassées. Il n'y a aucune raison que le javascript doive être monothread, et ce n'est pas le cas. Aujourd'hui, tous les navigateurs traditionnels prennent en charge les travailleurs, avant que ce ne soit le cas d'autres runtimes javascript comme Rhino et Node.js prennent en charge le multithreading.
'Javascript is single threaded' n'est pas une réponse valide. Par exemple, l'exécution d'une fonction de veille au sein d'un travailleur ne bloquerait aucun du code exécuté dans le thread d'interface utilisateur.
Dans les runtimes plus récents prenant en charge les générateurs et le rendement, on pourrait apporter des fonctionnalités similaires à la fonction de veille dans un environnement à thread unique:
Cette imitation du sommeil est différente d'une véritable fonction de sommeil car elle ne bloque pas le thread. C'est simplement du sucre en plus de la fonction setTimeout actuelle de javascript. Ce type de fonctionnalité a été implémenté dans Task.js et devrait fonctionner aujourd'hui dans Firefox.
la source
sleep
utilisant plusieurs travailleurs. Si vous utilisez les fonctions du générateur Node.js, elles sont déjà implémentées et peuvent être utilisées comme décrit. Les navigateurs traditionnels n'ont pas tous implémenté de générateurs à ce jour.J'ai recherché / googlé pas mal de pages Web sur le sommeil / l'attente de Javascript… et il n'y a PAS de réponse si vous voulez que Javascript soit à "RUN, DELAY, RUN" ... ce que la plupart des gens ont obtenu était "RUN, RUN (inutile ) "RUN" ou "RUN, RUN + RUN retardé" ....
J'ai donc mangé des hamburgers et j'ai réfléchi ::: voici une solution qui fonctionne ... mais vous devez couper vos codes de fonctionnement ... ::: oui, je sais, c'est juste un refactoring plus facile à lire .. . encore...
//......................................... //Exemple 1:
// .................................... // exemple2:
// ................. exemple3:
// .............. exemple4:
la source
la source
La solution la plus courte sans dépendances:
la source
await new Promise(function(resolve) { setTimeout(resolve, 5000); });
Vous ne pouvez pas faire un sommeil comme ça en JavaScript, ou, plutôt, vous ne devriez pas. L'exécution d'une veille ou d'une boucle while entraîne le blocage du navigateur de l'utilisateur jusqu'à ce que la boucle soit terminée.
Utilisez une minuterie, comme spécifié dans le lien que vous avez référencé.
la source
Un scénario où vous voudrez peut-être une fonction sleep () plutôt que d'utiliser setTimeout () est si vous avez une fonction répondant à un clic de l'utilisateur qui finira par ouvrir une nouvelle fenêtre contextuelle, et que vous avez initié un traitement qui nécessite une courte période pour terminer avant que la fenêtre contextuelle ne s'affiche. Déplacer la fenêtre ouverte dans une fermeture signifie qu'elle est généralement bloquée par le navigateur.
la source
Je peux comprendre le but d'une fonction de veille si vous devez gérer une exécution synchrone. Les fonctions setInterval et setTimeout créent un thread d'exécution parallèle qui renvoie la séquence d'exécution au programme principal, ce qui est inefficace si vous devez attendre un résultat donné. Bien sûr, on peut utiliser des événements et des gestionnaires, mais dans certains cas, ce n'est pas ce qui est prévu.
la source
Ajout de mes deux bits. J'avais besoin d'une attente occupée à des fins de test. Je ne voulais pas diviser le code car ce serait beaucoup de travail, donc un simple pour l'a fait pour moi.
Je ne vois aucun inconvénient à faire cela et cela a fait l'affaire pour moi.
la source
for
boucles s'exécutera presque toujours immédiatement, quelle que soit la valeur maximale dei
, et même avec du code mathématique complexe placé à l'intérieur. Donc, à moins que vous n'attendiez que quelques millisecondes, il ne semble toujours pas possible de dormir gracieusement dans JS.Cela peut être fait en utilisant la méthode de sommeil de Java. Je l'ai testé dans FF et IE et il ne verrouille pas l'ordinateur, ne mâche pas les ressources ou ne provoque pas de coups de serveur sans fin. Cela me semble une solution propre.
Vous devez d'abord charger Java sur la page et rendre ses méthodes disponibles. Pour ce faire, je l'ai fait:
Ensuite, tout ce que vous avez à faire lorsque vous souhaitez une pause indolore dans votre JS est:
Où xxx est le temps en millisecondes. Dans mon cas (à titre de justification), cela faisait partie de l'exécution des commandes back-end dans une très petite entreprise et je devais imprimer une facture qui devait être chargée depuis le serveur. Je l'ai fait en chargeant la facture (en tant que page Web) dans un iFrame puis en imprimant l'iFrame. Bien sûr, j'ai dû attendre que la page soit entièrement chargée avant de pouvoir imprimer, le JS a donc dû s'arrêter. J'ai accompli cela en ayant la page de facture (dans l'iFrame) changer un champ de formulaire caché sur la page parent avec l'événement onLoad. Et le code sur la page parent pour imprimer la facture ressemblait à ceci (pièces non pertinentes coupées pour plus de clarté):
Ainsi, l'utilisateur appuie sur le bouton, le script charge la page de facture, puis attend, vérifiant chaque quart de seconde pour voir si le chargement de la page de facture, puis ouvre la boîte de dialogue d'impression pour que l'utilisateur l'envoie à l'imprimante. QED.
la source
Beaucoup de réponses ne répondent pas (directement) à la question, et celle-ci non plus ...
Voici mes deux cents (ou fonctions):
Si vous voulez des fonctions moins maladroites que
setTimeout
etsetInterval
, vous pouvez les encapsuler dans des fonctions qui inversent simplement l'ordre des arguments et leur donnent de beaux noms:Versions de CoffeeScript:
Vous pouvez ensuite les utiliser correctement avec des fonctions anonymes:
Maintenant, il se lit facilement comme "après N millisecondes, ..." (ou "toutes les N millisecondes, ...")
la source
Pour le cas spécifique de vouloir espacer un ensemble d'appels en cours d'exécution par une boucle, vous pouvez utiliser quelque chose comme le code ci-dessous avec prototype. Sans prototype, vous pouvez remplacer la fonction de retard par setTimeout.
la source
Si vous êtes sur node.js, vous pouvez voir les fibres - une extension C native vers node, une simulation un peu multi-threading.
Il vous permet de faire un réel
sleep
d'une manière qui bloque l'exécution dans une fibre, mais il n'est pas bloquant dans le thread principal et d'autres fibres.Voici un exemple fraîchement extrait de leur propre fichier Lisez-moi:
- et les résultats sont:
la source