Qu'est-ce que la version JavaScript de sleep()?
Est-il une meilleure façon de concevoir un sleep
en JavaScript que les suivantes pausecomp
fonction (prises à partir 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 doublon de Dormir dans JavaScript - délai entre les actions; je veux un vrai sommeil au moyen d'une fonction, et non pas un délai avant qu'un morceau de code s'exécute.
- Il est situé dans le milieu d'un moment, si je utiliser setTimeout le tout continuera à traiter et de la file d'attente de plus setTimeouts qui finira par être en cours d'exécution dans le même temps, et en faisant un peu de simultanéité entre eux
- C'est une horrible solution que vous allez être à mâcher des cycles de traitement tout en ne faisant rien.
- La seule raison pour un sommeil est d'interrogation ou d'attente pour un rappel - setInterval et setTimeout faire mieux que cela.
- Probablement, vous pouvez faire ce que vous voulez avec la continuation passing style en JavaScript. Jetez un oeil à cet article.
Vous devez vous connecter pour publier un commentaire.
2017 — 2019 mise à jour
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é. Voici les meilleures pratiques en vigueur:
JS:
Ce qu'il est.
await sleep(<duration>)
.Noter que,
await
ne peuvent être exécutées que dans les fonctions préfixées avec leasync
mot-clé, ou à la haut niveau de votre script dans certains environnements (par exemple, le Chrome DevTools de la console, ou Runkit).await
seulement interrompt le courantasync
fonctionDeux nouvelles fonctions JavaScript contribué à la rédaction de ce "sommeil" de la fonction:
async/await
fonctionnalité permet au code explicitement attendre une promesse de règlement (résoudre ou de les rejeter).Compatibilité
async
/await
débarqué en V8 et a été activé par défaut depuis Chrome 55 (sorti en Décembre 2016)Si, pour une raison ou une autre, vous êtes à l'aide d'un Noeud âgés de plus de 7 (qui a atteint fin de vie), ou le ciblage de vieux navigateurs,
async
/await
peut encore être utilisé via Babel (un outil qui va transpile JavaScript + de nouvelles fonctionnalités dans le bon vieux JavaScript), avec latransformation-async-à-générateur
plugin.await new Promise(r => setTimeout(() => r(), 2000));
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
All other answers are now obsolete or overly complicated
, c'est vraiment une question de goût. Certains développeurs préfèrent recourir à des.then
chaînage ou un rappel, je ne vois rien de compliqué, avec qui...await sleep
à un certain point dans la boucle, la boucle va attendre la quantité spécifiée, puis continuer la boucle. Exemple de code.(Voir la mise à jour de réponse pour 2016)
Je pense qu'il est parfaitement raisonnable d'en souhaitez effectuer une action, attendre, puis effectuer une autre action. Si vous êtes habitué à l'écriture en multi-thread langues, vous avez probablement l'idée de céder à l'exécution pendant un certain temps jusqu'à ce que votre fils se réveille.
Le problème ici est que JavaScript est un thread unique événement à base de modèle. Alors que dans un cas spécifique, il peut être intéressant de disposer de l'ensemble moteur, attendez quelques secondes, en général, c'est une mauvaise pratique. Supposons que je voulais faire usage de vos fonctions lors de l'écriture de mon propre? Quand j'ai appelé votre méthode, mes méthodes seraient tous geler. Si JavaScript pourrait en quelque sorte de préserver votre fonction du contexte d'exécution, de le stocker quelque part, puis de le mettre en arrière et reprendre plus tard, puis le sommeil pourrait arriver, mais qui serait grosso modo le filetage.
Donc, vous êtes un peu coincé avec ce que d'autres ont suggéré-vous aurez besoin de casser votre code en plusieurs fonctions.
Votre question est un peu un faux choix, puis. Il n'y a pas moyen de dormir dans la manière que vous voulez, vous ne devriez pas poursuivre la solution que vous suggérez.
sleep()
n'est pas possible en JS, et que la plupart du temps il y a de meilleures façons de faire les choses. Mais je serais encore examiner la façon dont le moteur des liens de toutes choses jusqu'à être un défaut de conception; il n'y a aucune raison pour que le langage ne pouvait pas avoir unsleep()
fonction limité à un script, page, ou la fonction sans que le moteur casser le CPU et le gel de l'application comme un maniaque. C'est en 2015 et vous ne devriez pas être en mesure de crash de l'ensemble d'un navigateur web avecwhile(1)
. Nous avons un Flash pour ce genre de choses.En JavaScript, j'ai réécrire chaque fonction afin qu'il puisse prendre fin dès que possible. Vous souhaitez que le navigateur de retour dans la commande de sorte qu'il peut rendre votre DOM changements.
Chaque fois que j'ai voulu un sommeil au milieu de ma fonction, j'ai refait l'utilisation d'un
setTimeout()
.L'infâme sommeil, ou de retard, à la fonction dans n'importe quelle langue est beaucoup débattu. Certains diront qu'il devrait toujours être un signal ou d'un rappel à l'incendie d'une fonctionnalité donnée, d'autres affirment que, parfois, l'arbitraire d'un moment de retard est utile. Je dis qu'à chacun de leurs propres et d'une règle ne peut jamais dicter quoi que ce soit dans cette industrie.
L'écriture d'une fonction de veille est simple et utilisable avec JavaScript Promesses:
function foobar(el) { setTimeout(function() { foobar_cont(el); }, 5000); }
for(i=0; i<5; i++) { (function(i) { setTimeout(function() { console.log(i); }, 1000*i); })(i); }
$.ajax({ 'async': false });
almost
réponse: Hypnotique. coolwanglu.github.io/hypnotic/web/demo.htmlfoobar_cont_2.bind(this, "value"))
pour appeler la fonctionfoobar_cont_2(xXx)
setTimeout
ne pas DORMIR dans le milieu de votre fonction que vous avez indiqué. Votre fonction continue l'exécution. Tout le reste à l'intérieur de lasetTimeout
sera exécuté plus tard.alert("hi, i'm blocking execution");
? [...] Lorsque le message d'alerte apparaît, et sans l'écarter, je peux toujours accéder à la console de Chrome et de faire le débogage.Seulement pour debug/dev , je poste ceci si c'est utile à quelqu'un
Des choses intéressantes, dans Firebug ( & probablement d'autres js consoles ), rien ne se passe en appuyant sur entrée après, seulement après, la durée du sommeil spécifié (...)
Exemple d'utilisation:
only for debug/dev
... rolleyesasync/await
il ne réagit pas, malheureusement, et nous devons l'utiliser obligatoirement.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.
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.
function foo(index) { setTimeout(function() { foo_continue(index); }, 10000); }
etfor(var X = 0; X < 3;X++) { foo(X); }
- le valeur de X est passé dansfoo
, qui est ensuite réutilisé sous le nom deindex
quandfoo_continue
est finalement appelé.foo(index) { console.log(c[index-1]);
etfoo_continue(index) { c[index]=index; }
? Vous verrez que les résultats diffèrent si vous utilisezsetTimeout
ou fictifssleep()
de commande.console.log()
à l'intérieur defoo_continue()
dans le setTimeout version et vous obtenez le même résultat.Pour l'amour de $DIVINITÉ merci de ne pas faire un occupé-attendre une fonction de veille.
setTimeout
etsetInterval
faire tout ce dont vous avez besoin.sleep
pour quand ils ne le font pas. Vous n'avez pas besoin de busywait-le blocage de la JS moteur, vous devez diviser votre traitement danssetTimeout
.Je sais que c'est un peu une vieille question, mais si (comme moi), vous êtes à l'aide de Javascript avec Rhino, vous pouvez utiliser...
Si vous utilisez jQuery, quelqu'un a réellement créé un "retard" plugin qui n'est rien de plus qu'un wrapper pour setTimeout:
Vous pouvez ensuite l'utiliser dans une ligne d'appels de fonction comme prévu:
.delay()
fait partie de jQuery (mais avec la sémantique de la mise en œuvre). api.jquery.com/delayJ'ai cherché pour le sommeil solution trop (pas pour la production de code, uniquement pour les dev/tests) et 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/
Aussi, lorsque vous appelez
alert()
, votre code sera mis en pause trop, alors que l'alerte est affiché -- besoin de trouver un moyen de ne pas afficher l'alerte, mais obtenir le même effet. 🙂Ici vous allez. Comme le code dit, ne pas être un mauvais dev et l'utiliser sur des sites web. C'est un développement de la fonction d'utilité.
async/await
il ne réagit pas, malheureusement, et nous devons l'utiliser obligatoirement.Voici une solution simple à l'aide d'un synchrones XMLHttpRequest:
contenu de sleep.php:
Maintenant l'appeler avec:
sleep(5);
setTimeout()
si cela fonctionne, mais si cela signifie que le décryptage de 1000 lignes de rappels cela pourrait commencer de ne pas ressembler à une blague.Personnellement, j'aime le simple:
alors:
Je l'utilise tout le temps pour créer de faux temps de chargement lors de la création de scripts dans P5js
Première:
Définir une fonction que vous voulez exécuter comme ceci:
Puis de planifier son exécution avec la méthode setTimeout:
Remarque deux choses
Meilleure solution pour faire des choses qui ressemblent à ce que la plupart des gens veulent, c'est d'utiliser une fonction anonyme:
C'est probablement le plus proche que vous obtiendrez à quelque chose qui n'existe tout simplement ce que vous voulez.
Remarque, si vous avez besoin de plusieurs couchages cela peut devenir laid pressé et que vous pourriez réellement besoin de repenser votre conception.
Pour les navigateurs, je suis d'accord que setTimeout et setInterval sont la voie à suivre.
Mais pour le code côté serveur, il peut exiger une fonction de blocage (par exemple, de sorte que vous pouvez effectivement avoir des threads synchronisation).
Si vous êtes en utilisant node.js et meteor, vous avez exécuté dans les limites de l'utilisation de setTimeout dans une fibre. Voici le code côté serveur sommeil.
Voir: https://github.com/laverdet/node-fibers#sleep
Je résumerait setTimeOut dans une Promesse pour le code de la cohérence avec d'autres tâches asynchrones : la Démo en Violon
Utilisé comme ça :
Il est facile de se souvenir de la syntaxe si vous utilisez les Promesses.
La plupart des réponses ici sont erronées ou à tout le moins obsolète. Il n'y a pas de raison javascript doit être mono-thread, et en effet il n'est pas. Aujourd'hui, tous les intégrer des navigateurs prennent en charge les travailleurs, avant c'était le cas d'autres javascript runtimes comme le Rhinocéros et le Node.js pris en charge le multithreading.
'Javascript est mono-thread" n'est pas une réponse valable. Par exemple l'exécution d'une fonction de veille au sein d'un travailleur n'aurait pas bloquer tout le code qui s'exécute dans le thread de l'interface utilisateur.
Dans de nouveaux environnements d'exécution de soutien et des générateurs de rendement, on pourrait apporter des fonctionnalités similaires à celles de la fonction de veille dans un seul thread de l'environnement:
Cette imitation de sommeil est différente à partir d'un vrai sommeil de la fonction que de ne pas bloquer le thread. C'est tout simplement du sucre sur le dessus de javascript actuel de la fonction setTimeout. Cette fonctionnalité type a été mis en œuvre dans Task.js et doit travailler aujourd'hui dans Firefox.
sleep
à l'aide de plusieurs travailleurs. Si vous utilisez Node.js générateur de fonctions sont déjà mises en œuvre et peut être utilisé comme décrit. Les navigateurs grand public n'ont pas toutes mis en œuvre des générateurs d'aujourd'hui.J'ai cherché/googlé tout à fait un peu de pages sur javascript/sommeil attendre... et il n'y a PAS de réponse, si vous voulez javascript "d'EXÉCUTION, de RETARD, de COURIR"... ce que la plupart des gens ont été soit, "RUN, RUN(inutiles), EXÉCUTER" ou "RUN, RUN + retardé RUN"....
Donc j'ai mangé des hamburgers et eu la pensée:::
voici une solution qui fonctionne... mais vous devez couper votre exécution de codes...:::
oui, je sais, c'est juste un plus facile à lire refactoring... encore...
//.........................................
//exemple1:
//....................................
//exemple2:
//.................
exemple3:
//..............
exemple4:
Un scénario où vous voudrez peut-être un sleep() de la fonction plutôt que d'utiliser setTimeout() si vous avez une fonction de répondre à un clic de l'utilisateur qui sera finalement l'ouverture d'un nouveau c'est à dire la fenêtre popup et que vous avez commencé un traitement qui nécessite une courte période afin de terminer avant que le popup s'affiche. Le déplacement de la fenêtre ouverte dans une fermeture signifie qu'il obtient généralement bloqué par le navigateur.
Je peux comprendre le but d'une fonction de veille si vous avez à traiter avec l'exécution synchrone. La fonction setInterval et setTimeout fonctions de mettre en parallèle un thread d'exécution qui retourne la séquence d'exécution de retour au programme principal, qui n'est pas efficace si vous devez attendre pour un résultat donné. Bien sûr, on peut utiliser les événements et les gestionnaires, mais dans certains cas, n'est pas ce qui est prévu.
L'ajout de mes deux bits. J'avais besoin d'un occupé-attendre à des fins de test. Je n'ai pas envie de diviser le code en tant que ce serait beaucoup de travail, donc un simple pour fait pour moi.
Je ne vois aucun inconvénient à le faire et ça a fait l'affaire pour moi.
for
boucles seront presque toujours exécuter immédiatement, indépendamment de la valeur max pouri
, et même avec les mathématiques complexes code placé à l'intérieur. Donc, sauf si vous êtes en attente pour les quelques millisecondes, il semble toujours y avoir aucun moyen de sommeil en douceur en JS.Il peut être fait à l'aide de Java de la méthode sleep. Je l'ai testé dans FF et IE, et il n'est pas verrouiller l'ordinateur, mâcher des ressources, ou de causer sans fin de serveur de frappe. Semble comme une solution propre pour moi.
Vous devez d'abord obtenir Java chargé sur la page et de faire ses méthodes disponibles. Pour ce faire, j'ai fait ceci:
Ensuite, tout ce que vous avez à faire lorsque vous voulez un indolore pause dans votre JS est:
Où xxx est le temps en millisecondes. Dans mon cas (par la voie de la justification), c'était de la partie back-end de l'exécution des commandes à une très petite entreprise et j'ai besoin d'imprimer une facture qui devait être chargé à partir du serveur. Je l'ai fait par le chargement de la facture (comme une page web) dans une iFrame et l'impression de l'iFrame. Bien sûr, j'ai dû attendre jusqu'à ce que la page est entièrement chargée avant que je puisse l'imprimer, de sorte que le JS de faire une pause. Je l'ai accompli en ayant la page de la facture (dans l'iFrame) modifier un champ de formulaire masqué sur la page parent avec l'événement onLoad. Et le code sur la page parent pour imprimer la facture ressemblait à ça (sans pertinence des pièces de découpe pour plus de clarté):
De sorte que l'utilisateur appuie sur le bouton, le script charge la page de la facture, puis attend, en vérifiant à chaque quart de seconde pour voir si la facture de la page a fini de se charger, puis affiche la boîte de dialogue d'impression pour l'utilisateur afin de l'envoyer à l'imprimante. CQFD.
Un grand nombre de réponses n'est pas (directement) de répondre à la question, et pas plus que celui-ci...
Voici mes deux cents (ou fonctions):
Si vous voulez moins maladroit de fonctions que
setTimeout
etsetInterval
, vous pouvez les envelopper dans des fonctions qui vient de renverser l'ordre des arguments et de leur donner de nice noms:CoffeeScript versions:
Vous pouvez ensuite les utiliser bien avec les fonctions anonymes:
Maintenant, il se lit facilement comme "après les N millisecondes, ..." (ou "toutes les N millisecondes, ...")
Vous ne pouvez pas faire un sommeil comme en JavaScript, ou, plutôt, vous ne devriez pas. L'exécution d'un sommeil ou une boucle while va provoquer le navigateur de l'utilisateur pour bloquer jusqu'à ce que la boucle est terminée.
Utiliser un timer, comme indiqué dans le lien que vous l'avez mentionné.
Pour le cas spécifique de vouloir faire de l'espace un ensemble d'appels en cours d'exécution par une boucle, vous pouvez utiliser quelque chose comme le code ci-dessous avec le prototype. Sans prototype, vous pouvez remplacer la fonction de délai avec setTimeout.
Si vous êtes sur node.js vous pouvez jeter un oeil à les fibres – native C extension pour le nœud, un peu-le multi-threading de simulation.
Il permet de faire un vrai
sleep
dans une manière qui est bloquant l'exécution dans une fibre, mais c'est non-bloquant dans le thread principal et d'autres fibres.Voici un exemple tout frais de leur propre readme:
– et les résultats sont les suivants:
Une vieille question, à partir de 2009. Maintenant, en 2015, une nouvelle solution est possible avec des générateurs définis dans ECMAscript 2015 aka ES6. Il a été approuvé en juin, mais il a été implémenté dans Firefox et Chrome avant. Maintenant une fonction de veille peut être rendu non-occupé, non-blocage et imbriquées à l'intérieur des boucles et sous-fonctions, sans le figer le navigateur. Seule la pure JavaScript est nécessaire, pas de bibliothèques ou de cadres.
Le programme ci-dessous montre comment
sleep()
etrunSleepyTask()
peut être faite. Lesleep()
fonction est uniquement unyield
déclaration. Il est tellement simple qu'il est en fait plus facile d'écrire leyield
déclaration directement en lieu et place de l'appel desleep()
, mais alors il n'y aurait pas de sommeil du tout-mot 🙂 Le rendement renvoie une valeur de temps à lanext()
méthode à l'intérieur d'wakeup()
et attend. Le "sommeil" se fait danswakeup()
en utilisant le bon vieuxsetTimeout()
. Au rappel de lanext()
méthode déclenche layield
déclaration de continuer, et de la "magie" de rendement est que toutes les variables locales et de l'ensemble de la pile des appels autour de lui, est encore intact.Fonctions qui utilisent un sleep() ou de rendement doivent être définies comme des générateurs. Facile fait par l'ajout d'un astérisque, pour le mot-clé
function*
. Pour exécuter un générateur est un peu plus compliqué. Lorsqu'il est invoqué avec le mot-clénew
le générateur retourne un objet qui a lanext()
méthode, mais le corps du générateur n'est pas exécutée (le mot-clénew
est facultative et ne fait pas de différence). Lenext()
méthode déclenche l'exécution de la génératrice du corps jusqu'à ce qu'il rencontre unyield
. La fonction wrapperrunSleepyTask()
démarrage de la table de ping-pong:next()
attend unyield
, etyield
attend unnext()
.Une autre façon d'appeler un générateur est avec le mot-clé
yield*
, ici, il fonctionne comme un simple appel à la fonction, mais il comprend aussi la capacité de rendement jusqu'ànext()
.Cela est démontré par l'exemple
drawTree()
. Il dessine un arbre avec des feuilles sur une rotation 3D de la scène. Un arbre est dessiné comme un tronc avec 3 pièces en haut dans des directions différentes. Chaque partie est ensuite établi comme un autre, mais en plus petit arbre en appelantdrawTree()
de manière récursive après une courte nuit de sommeil. Un très petit arbre est dessiné comme seulement une feuille.Chaque feuille a sa propre vie dans une autre tâche a commencé avec
runSleepyTask()
. Il naît, grandit, s'assied, s'arrête, tombe et meurt dansgrowLeaf()
. La vitesse est contrôlée avecsleep()
. Cela démontre comment il est facile de multitâche qui peut être fait.JS:
HTML:
La 3D est caché à l'intérieur setup3D() et est fourni uniquement pour le rendre moins ennuyeux que de la console.log(). Les anges sont mesurés en radians par la voie.
Testé pour fonctionner dans les navigateurs Firefox et Chrome. Pas implémenté dans Internet Explorer et iOS (ipad). Essayez d'exécuter vous-même.
Après un autre passage de réponses que j'ai trouvé, que Gabriel Ratener fait la même réponse il y a un an: https://stackoverflow.com/a/24401317/5032384
Tout d'abord - setTimeout et setInterval est ce que devrait être utilisé, en raison de javascript de rappel du-ish de la nature. Si vous souhaitez utiliser
sleep()
c'est le flux de contrôle ou à l'architecture de votre code est incorrect.Avoir dit que je suppose que je peux aider avec deux mise en œuvre d'un sommeil.
semblant synchrone exécuter sur le dessus de ma tête:
[rend la lecture automatique devrait également être possible]
réel synchrone exécuter
Je lui ai donné beaucoup de pensée d'un jour et la seule idée que j'ai eu pour un vrai sommeil en javascript est technique.
une fonction de veille devrait être un synchrone appel AJAX avec un délai d'attente fixé à la valeur de veille. C'est tout et une seule façon d'avoir un réel
sleep()
Si vous avez droit une fonction de veille comme ce
et vous avez un asynchrones fonction à appeler plusieurs fois
Et vous l'installation de votre projet comme celui-ci:
Ensuite, vous pouvez faire ceci:
Au lieu d'infinies de rappel de l'indentation comme ceci:
Depuis le Nœud de 7,6, vous pouvez combiner les
promisify
fonction de la utils module avecsetTimeout
.Générales D'Utilisation
Question De L'Utilisation
Code à partir de ce lien ne gèlera pas comp. Mais il ne fonctionne que sur ff.
Dans le cas où vous avez vraiment besoin d'un sleep() juste pour tester quelque chose. Mais sachez que ça va planter le navigateur la plupart du temps, tout en debuggin - c'est probablement pourquoi vous avez besoin de toute façon. Dans le mode de production, je vais commenter cette fonction.
Ne pas utiliser de new Date() dans la boucle, sauf si tu veux perdre de la mémoire, de puissance de traitement, de la batterie et, éventuellement, la durée de vie de votre appareil.
Ce n'est vraiment pas une bonne idée, de faire quelque chose comme cela serait la cause de la totalité de la page à geler pendant que le système attendu pour votre fonction de retour.
Si vous le souhaitez, un conseiller à pas de perte de performance .
setTimeout
est prévuesleep
.Toutefois , si vous voulez une syntaxe dont le code est "divisé en son milieu" par
sleep
, nous pouvons faire :puis , perpare fonctions suivantes :
Alors :
YEP! ٍpoint de vue syntaxique,Il est très proche :
Embrasser le système de la nature de javascript!
Toutes les suivantes seront de retour immédiatement, mais ont un seul lieu de mettre le code que vous voulez courir après quelque chose qui s'est passé.
Les méthodes que j'ai décrites ici sont tous à différents cas d'utilisation et sont grossièrement classés en fonction de leur complexité.
Les différentes choses sont comme suit:
Attendre
En attendant de voir si une certaine condition est vrai, c'est usedful où il n'est pas accessible de rappel pour vous dire quand quelque chose a fini de s'exécuter.
C'est une jolie mise en œuvre de base qui suppose que la condition devienne vraie à un certain point. Avec un peu de bricolage, il pourrait être élargi afin d'être encore plus utiles (par exemple par la fixation d'un appel de limite). (J'ai seulement écrit ce un hier!)
code d'appel:
Ici, je vais appeler quelque chose qui charge un extjs "stocker" et attendre jusqu'à ce que le magasin contient quelque chose avant de continuer (la beforeEach est un jasmin framework de test de chose).
Attendre plusieurs choses à terminer
Une autre chose que j'avais à faire était d'utiliser un seul rappel après une charge de différentes méthodes fini. Vous pouvez le faire comme ceci:
code d'appel:
Vous avez juste à attendre pour les notifications ou peut encapsuler également d'autres fonctions qui utilisent les valeurs passées à la fonction. Lorsque toutes les méthodes sont appelés alors
done
sera exécuté.Cours d'exécution asynchrone et les méthodes d'
J'ai utilisé une approche différente lorsque j'ai eu une série de méthodes asynchrones à appeler dans une rangée (de nouveau dans les tests). C'est un peu comme quelque chose que vous pouvez obtenir dans la bibliothèque Asynchrone de la série est d'environ la même chose et j'ai eu un peu de lecture de la bibliothèque d'abord pour voir si il fait ce que je voulais. Je pense que le mien a une belle api pour travailler avec des tests (+ c'était amusant de le mettre en œuvre!).
code d'appel:
PartiallyApplyTo ici est essentiellement une version renommée de Doug Crockford de la mise en œuvre de Curry. Beaucoup de choses que je suis en train de travailler avec prend un rappel que le dernier argument simple, les appels peuvent être fait de cette manière plutôt que d'avoir à envelopper le tout avec une touche func.
Nous espérons que certaines des idées, il pourrait être utile aux gens.
Je sais que la question est à propos du sommeil, et clairement, la réponse est qu'il n'est pas possible. Je pense que d'un commun vouloir de sommeil est de gérer les tâches asynchrones dans l'ordre, je sais que j'ai eu à traiter avec elle, pour sûr.
De nombreux cas peuvent être en mesure d'utiliser des promesses (requêtes AJAX usage commun). Ils vous permettent de faire asynchrone les choses dans une manière synchrone. Il y a aussi la manipulation de la réussite/l'échec, et ils peuvent être enchaînés.
- Ils partie d'ECMAScript 6, donc prise en charge du navigateur n'est pas encore là, principalement, c'est à dire ne pas les soutenir. Il est aussi appelé bibliothèque Q pour faire des promesses.
Références:
http://www.html5rocks.com/en/tutorials/es6/promises/
https://github.com/jakearchibald/es6-promise#readme (Shim pour les plus âgés, ou IE navigateurs)
Essayez ce simple fonction javascript:
Remarque: Cette fonction ne fonctionne que sur web de travailleurs.
Avec
await
de soutien et de bluebird promesse:await bluebird.delay(1000);
Cela fonctionne comme un synchrones
sleep(1)
de langage c. Ma solution préférée.Une fonction de veille, à l'aide d'un appel synchrone de laisser l'OS le faire.
L'utilisation de n'importe quel OS commande de mise en veille vous le souhaitez. Il n'est pas occupé d'attente dans le sens de l'utilisation du temps CPU.
J'ai choisi de ping sur un inexistant adresse.
Un test pour vérifier qu'elle fonctionne
Et certains résultats de tests.
(et au bout de 10 secondes)
Cela vous fera l'affaire.
JS:
assurez-vous que votre fonction d'appel est asynchrone
vérifié et à travailler à
Une méthode d'un objet qui a besoin d'utiliser un "sommeil" de la méthode telle que la suivante:
Peut presque être traduit:
La différence est que l'opération de "SomeMethod" renvoie avant l'opération "DoSomething2" est exécuté. L'appelant de "SomeMethod" ne peut pas compter sur cela. Depuis le "Sommeil" de la méthode n'existe pas, j'utilise le plus tard méthode et la conception de mon code en conséquence.
J'espère que cette aide.
Si vous voulez dormir une fonction anonyme comme celui que vous avez créé en tant que gestionnaire, je recommande ce qui suit:
Ce code dit "Si la condition d'attente n'a pas encore été satisfaits, appeler cette fonction à nouveau avec ces arguments." J'ai utilisé cette méthode pour passer dans les mêmes arguments à ma gestionnaires, le rendant de ce code, un non-interrogation sleep() (qui ne fonctionne qu'au début de votre fonction).
Vous pouvez utiliser une fermeture d'appel setTimeout() avec progressivement de plus grandes valeurs.
Résultat:
Il y a une nouvelle bibliothèque proprement chaînes de fonctions en collaboration avec des délais d'attente de sorte que vous pouvez éviter de rappel de l'enfer.
Sequencr.js
Transforme ce:
dans cette:
Et a un support intégré pour les boucles qui "veille" entre chaque itération.
Le problème avec la plupart des solutions ici, c'est qu'ils rembobiner la pile. Cela peut être un gros problème dans certains cas.Dans cet exemple, je montre comment utiliser des itérateurs de manière différente à simuler vrai sommeil
Dans cet exemple, le générateur est l'appel de son propre
next()
donc, une fois ça va, il est sur son propre.2019 mise à Jour à l'aide de Atomics.attendre
Devraient travailler en Nœud 9.3 ou plus.
J'avais besoin d'un assez précis de la minuterie dans Node.js et il fonctionne très bien pour cela.
Cependant, il semble qu'il y est extrêmement limité de support dans les navigateurs.
JS:
A couru quelques 10 secondes de la minuterie de repères.
Avec setTimeout j'obtiens une erreur allant jusqu'à 7000 microsecondes. (7ms)
Avec Atomics mon erreur semble rester moins de 600 microsecondes. (0.6 ms)
Une bonne alternative dans certaines situations, c'est d'afficher un haut niveau de panneau de message pour arrêter l'interaction de l'utilisateur, puis le cacher à nouveau lorsque vous obtenez le résultat que vous êtes en attente pour (de manière asynchrone). Qui permet au navigateur de continuer avec des tâches en arrière-plan, mais interrompt le flux de travail jusqu'à ce que vous avez votre résultat en retour.
- Je utiliser le multithread HTML5 Travailleur qui sera en mesure d'interrompre une synchrones XMLHttpRequest pointant vers un qui ne répond pas de l'URL. Ce n'est pas de bloquer le navigateur.
https://gist.github.com/el-gringo/6990785
La réponse courte est PAS, pas en javascript par lui-même. Vous la solution qui semble être la seule façon de ne pas revenir en arrière à l'environnement.
Cela est nécessaire si l'environnement ne prend pas en charge les événements. Ils ne seraient probablement pas en charge le settimeout soit.
settimeout est certainement la meilleure façon si vous êtes dans l'organisation d'une manifestation de l'environnement tel que d'un navigateur ou d'node.js.
Pour résumer (comme il a été dit dans les réponses précédentes):
Il n'est pas intégré dans le sommeil de la fonction en JavaScript. Vous devez utiliser setTimeout ou setInterval pour obtenir un effet similaire.
Si tu le voulais vraiment, vous pouvez simuler la fonctionnalité de veille avec une boucle for comme montré dans la question d'origine, mais ce serait faire de votre CPU à travailler comme un fou. À l'intérieur d'un Web Worker une solution alternative serait de faire un synchrones
XMLHttpRequest
à un non-réactif IP et définir un bon délai. Cela permettrait d'éviter l'utilisation de l'UC problème. Voici un exemple de code:JS:
Je naviguer la solution pour un jour, mais toujours penser à la façon de maintenir la possibilité d'enchainement en utilisant la fonction de rappel. Tout le monde est familier avec la programmation traditionnelle de style qui exécute le code ligne par ligne de manière synchronisée. SetTimeout utilise une fonction de callback pour que la prochaine ligne ne pas attendre qu'elle se termine. Cela me laisse penser comment le faire "sync", de façon à faire un "sommeil" de la fonction.
Début avec un simple coroutine:
Je veux dormir 3 secondes dans le milieu, mais ne veulent pas dominer l'ensemble de l'écoulement, de sorte que la coroutine doit être exécuté par un autre thread. Je considère que le L'Unité YieldInstruction, et de modifier la coroutine le suivant:
Déclarer la sleepFor prototype:
Après l'exécution de la coroutine1 (je l'ai testé dans IE11 et Chrome49), vous verrez le sommeil de 3 secondes entre les deux console consolidés. Il conserve les codes joli que le style traditionnel. Le plus compliqué est en sleepFor routine. Il lit l'appelant corps de la fonction en tant que chaîne et le diviser en 2 parties. Retirer la partie supérieure et de créer une autre fonction par la partie inférieure. Après avoir attendu que le nombre de millisecondes spécifié, il appelle à la création de la fonction en appliquant le contexte d'origine et d'arguments. Pour le flux d'origine, il va finir par "retour", comme d'habitude. Pour le "rendement"? Il est utilisé pour l'expression rationnelle correspondant. Il est nécessaire mais pas à tous.
Il n'est pas parfait à 100%, mais il atteint mes emplois au moins. Je dois mentionner certaines limites dans l'aide de cette pièce de codes. Comme le code est cassé en 2 parties, le "retour" déclaration doit être à l'extérieur, à la place d'une boucle ou {}. c'est à dire
Les codes ci-dessus doivent avoir de problème, car le fermer la parenthèse ne pourrait pas exister individuellement dans la fonction. Une autre limitation est toutes les variables locales déclarées par "var xxx=123" ne pouvait pas transporter à la fonction suivante. Vous devez utiliser "ce.xxx=123" pour obtenir la même chose. Si votre fonction a des arguments et ils ont eu des changements, de la modification de la valeur ne peut pas non plus procéder à la fonction suivante.
Je voudrais introduire un autre prototype de fonction: waitFor
Il attend pour le "check" de la fonction jusqu'à ce qu'elle retourne true. Il vérifie la valeur de toutes les 100ms. Vous pouvez l'ajuster en passant argument supplémentaire. Envisager le test coroutine2:
Également dans un joli style que nous aimons beaucoup. En fait, je déteste le imbriquée de rappel. Il est facilement compréhensible que le coroutine2 va attendre la fin de coroutine1. Intéressante? Ok, puis exécutez les codes suivants:
La sortie est:
Extérieure est immédiatement terminé après avoir initialisé coroutine1 et coroutine2. Ensuite, coroutine1 va attendre 3000ms. Coroutine2 permettra d'entrer dans l'étape 2 après avoir attendu pendant 500ms. Après, on va continuer à l'étape 3 une fois qu'il détecte la coroutine1.valeurs > 100.
Méfiez-vous de cela il y a 3 contextes de tenir variable "a". L'un est extérieur, dont les valeurs sont de 10 et 11. Un autre est en coroutine1, dont les valeurs sont de 100 et 101. Le dernier est en coroutine2, dont les valeurs sont 1, 2 et 3. Dans coroutine2, il attend également pour les c de.un qui vient de coroutine1, jusqu'à ce que sa valeur est supérieure à 100. 3 contextes sont indépendants.
L'ensemble du code pour copier&coller:
Il est testé dans IE11 et Chrome49. Parce qu'il utilise des arguments.le destinataire de l'appel, de sorte qu'il peut être un problème si elle fonctionne en mode strict.
Si vous vraiment souhaitez mettre en pause un script, vous pouvez le faire:
C'est probablement exactement ce que vous voulez si vous utilisez une boucle de toute façon, et vous pouvez modifier d'une manière de sorte que vous avez un pseudo-multi-threading, où vous avez quelques fonctions un peu de temps et les autres fonctionnent normalement. J'en utilise tout le temps pour les pur-JS jeux.
À côté serveur, vous pouvez utiliser le deasync
sleep()
méthode, qui est nativement mis en œuvre dans C de sorte qu'il peut mettre en œuvre efficacement un attendre effet, sans blocage de la événement en boucle ou mettre votre PROCESSEUR à 100% de charge.Exemple:
Mais, si vous avez besoin d'un pur fonction javascript (par exemple, pour l'exécuter à côté client par un navigateur), je suis désolé de dire que je pense que votre
pausecomp()
fonction est la seule façon de s'en approche et, plus que cela:Qui s'interrompt pas seulement la fonction, mais l'ensemble de la boucle d'événements. Donc pas d'autres événements sera assisté.
Il met à votre cpu à 100% de charge.
Donc, si vous en avez besoin pour un navigateur de script et ne veulent pas que ces effets terribles, je dois dire que vous devriez revoir votre fonction en un sens:
un). Vous pouvez vous le rappeler (ou l'appel à un
do_the_rest()
fonction) à un délai d'attente. La manière la plus simple si vous n'attendons aucun résultat de votre fonction.b). Ou, si vous avez besoin d'attendre un résultat, alors vous devez vous déplacer à l'aide de promesses (ou un rappel de l'enfer, bien sûr ;-)).
Aucun résultat prévu exemple:
Exemple de retour d'une promesse (avis il modifie votre utilisation de fonction):
J'ai eu cette question depuis longtemps et la réponse dont j'avais besoin n'était pas exactement ce qui a été présenté ici. Cette fonction d'attente de causes synchrone d'attente qui ne monopolise pas le cpu. waitForIt fait une requête ajax n'importe où et définit la async drapeau à false. waitF fait de même avec un cadre et waitD fait de même avec un div. Ajax prend environ 100 ms, le cadre est d'environ 25, et le div est d'environ 1. La fonction d'attente tire parti de l'ensemble de ces en fonction de la façon dont beaucoup de temps vous lui donnez. Si elle n'a pas attendu assez longtemps, puis le faire à nouveau. J'ai besoin de ce moment de traiter avec de multiples chargement asynchrone des éléments. Fondamentalement, pour "attendre jusqu'à ce que cet élément existe". Vous pouvez jouer avec elle ici https://jsfiddle.net/h2vm29ue/ juste exploite les choses que le navigateur naturellement attend. Version longue https://jsfiddle.net/5cov1p0z/32/ est plus précis.
Fonctions Javascript permettent pas de suspension. Synchrone Javascript de l'application des procédures. Les procédures attendent les opérations d'e/s et le sommeil des délais d'attente. Disponible pour javascript 1.7.
démos:
démo de sommeil
démo suspendable procédures
De garder le thread principal occupé pendant quelques millisecondes:
J'ai eu un problème similaire, avoir à attendre pour le contrôle de l'existence et de la vérification dans les intervalles.
Depuis il n'y a pas de vrai sommeil, d'attente ou de pause en JavaScript et en utilisant les attendent /async n'est pas pris en charge correctement dans Internet Explorer, j'ai fait une solution à l'aide de setTimeOut et de l'injection de la fonction en cas de succès à trouver l'élément.
Voici l'exemple complet de code, afin que chacun puisse les reproduire et de les utiliser pour leur propre projet:
Un moyen très simple de faire un sommeil, qui SERA compatible avec tout ce qui est Javascript... Ce code a été testé avec quelque chose comme 500 entrées, PROCESSEUR et de la mémoire n'est toujours pas visible sur mes navigateurs.
Ici une fonction d'attendre jusqu'à ce que le nœud devient visible...
Cette fonction crée un nouveau contexte
function () {}
pour éviter la récursivité. Nous avons placé un code qui fait la même chose que l'appelant code à l'intérieur de ce nouveau contexte. Nous utilisons la fonctionTimeout
à appeler notre fonction après un peu de temps à la seconde.J'ai obtenu la Promesse n'est pas un constructeur à l'aide de la réponse sommet. Si vous importez bluebird vous pouvez le faire. La plus simple solution de l'omi.
Le problème avec l'aide d'une réelle fonction de veille, c'est que JavaScript est monothread et une fonction de veille sera très bien faire votre onglet de navigateur bloquer pendant cette durée.
Je suis sûr qu'il ya un million de façons de le faire mieux, mais j'ai pensé que je donnerais un essai en créant un objet:
et à utiliser comme:
//////COMMENCER :: TEST //////
J'ai récemment eu un cas dans le code à la suite d'un rappel a été exécuté avant le rappel de la
$.ui.popup
avaient exécuté. Ma solution a été de définir une variable avant de la main appelé pause, attribuez la valeur true, l'exécution du$.ui.popup
code, alors le code que j'ai dû attendre dans un intervalle. exemple:Une autre voie possible est:
Utiliser trois fonctions:
setInterval
pour démarrer la boucleclearInterval
pour arrêter la boucle, puis appellesetTimeout
pour dormir, et, enfin, les appels à l'intérieur de lasetTimeout
comme le rappel pour redémarrer la boucleclearInterval
après le nombre maximal a été atteintJS:
Références
Développement D'Un Jeu À L'Aide De JavaScript
Pourquoi l'Événement Scroll Changement dans iOS 8 est une Grosse Affaire
En direct d'un système de sondage en Ember.js
La conduite de l'Animation avec requestAnimationFrame()
MDN: JavaScript Simultanéité Modèle et la Boucle d'Événements
Études De Réseau: Node.js
Battre 60fps en JavaScript
Partie 2: l'UC javascript calculs sans bloquer le thread unique
Je préfère cette style fonctionnel
sleep
fonction:Ici est une façon de dormir dans un
.hta
script, tel que, lorsque le script se réveille, il exécute la commande suivante dans la séquence, comme cela est nécessaire dans une boucle. C'est un vrai sommeil; il ne garde pas un processeur occupé pendant le sommeil. E. g. le processeur est capable de télécharger et d'afficher les pages pendant le sommeil.Juste une fois, vers le début du code, allez
Pour un sommeil de par exemple 1 seconde = 1000 millisecondes, exécutez l'instruction
Dans le même répertoire que le script est le fichier
Sleep.js
, qui contient une seule ligne:(Méfiez-vous;
0
est entre parenthèses, pas de crochets). La dernière est la ligne qui effectue réellement le sommeil. L'argumenttrue
dans le précédent extrait fait l'appel synchrone. Le3
dans le précédent argument semble ne pas avoir aucun effet, mais vous avez besoin d'un argument de sorte quetrue
est le 3ème argument. Microsoft affirme que "L'objet WScript ... ne doivent jamais être instancié avant d'appeler ses propriétés et ses méthodes, et il est toujours disponible à partir de tout fichier de script.", mais ce n'est pas vrai. Il est disponible dans un.js
fichier comme ci-dessus, mais apparemment pas dans un.js
fichier utilisé par une.hta
fichier, de sorte que c'est pourquoi il doit être dans un fichier séparé, qui est invoquée comme ci-dessus.Dans Livescript (qui est compilé en Javascript), vous pouvez le faire comme suit:
setTimeout
dans une fonction appeléesleep
:pIl est maintenant également possible d'utiliser le module natif util pour promisify régulièrement les fonctions de synchronisation.
await
à l'intérieur d'un non-async
fonction (dans votre exemple, la fonction exportée)Cela pourrait fonctionner. Il a travaillé pour moi dans c et javascript.
setTimeout()
ousetInverval()
au lieusomethingHappened
fonction.somethingHappened
était une fonction, l'alerte ne sera jamais appelé ainsi parce qu'il ne serait jamais égal à 1. Vraiment cet exemple ne doit pas dire== 1
parce que c'est censé être juste un espace réservé à l'état, et parce que vous ne devriez pas utiliser les nombres comme des booléens et même si vous êtes, vous n'avez pas besoin de la== 1
.Ou tout simplement créer ceci:
ce sera juste attendre l'intervalle de temps spécifié et appeler la fonction qui va tout simplement ne rien faire.
// do something else
continuera immédiatement.setInterval(myFunc, 1000)
.setTimeout(myFunc, 1000)
. 2. Le premier argument doit être la fonction elle-même [myFunc
], et non pas le résultat de la fonction [donné parmyFunc()
]. 3. L'OP explicitement voulua real sleep in a middle of a function, not a delay for a piece of code.
Ça pourrait être un peu tard et un peu paresseux et un peu ennuyeux ou un peu intrusive ou un peu comme "de grands", mais...
Chaque et toute solution que j'ai lu jusqu'à présent comme "let's get à dormir et à regarder ce qui s'est passé, demain".
setInterval(callback, temps) qu'il serait temps d'attente long et ensuite appeler la fonction de rappel, ALORS que le blocage de l'exécution. L'implémentation actuelle de "setInterval" est loin d'être thread-save, même pas à l'esprit de la simultanéité.
Tandis que les rares solutions mentionnées ressembler, devinez quoi, C# (rires), ils ne fonctionnent toujours pas comme en C#/.NET. Ils ont encore du travail comme en C.
JavaScript ne prévoit PAS actuellement d'une architecture à vraiment faire du multi-threading. La meilleure approche serait Tapuscrit, mais toujours ce manque tellement d'une véritable solution qu'il... fait mal. JavaScript et jQuery et AJAX, et jNode, et même Tapuscrit sommes juste un groupe d'Aspirants en s'appuyant sur les biens et les maux de l'humeur des réalisateurs. Fait. Arrêt complet.
setInterval
ne bloque pas - et, plus important encore, il se répète tous lestime
. Ce n'est même pas proche de ce qui est demandé.