Attendez jusqu'à ce flag=true
J'ai de la fonction javascript comme ceci:
function myFunction(number) {
var x=number;
...
... more initializations
//here need to wait until flag==true
while(flag==false)
{}
...
... do something
}
Le problème est que le javascript est bloqué dans le temps et collé mon programme. donc ma question est comment puis-je attendre dans le milieu de la fonction jusqu'à ce que le drapeau est vrai sans "occupé-attendre"?
- Utilisez la promesse modèle pour vos initialisations - peuvent être trouvés en assez certaines bibliothèques, comme
jQuery.Deferred
,Q
,async
, ... - exactement où utiliser et comment?
- Il ya beaucoup de tutoriels autour de décrire la promesse implémentations des différentes bibliothèques, par exemple. jQuery.Différés ou Q. Btw, votre problème sous-jacent est le même que dans cette question.
- Pour quelqu'un de lire ce qu'en 2018, les Promesses sont pris en charge par tous les navigateurs, en plus de opera mini et IE11.
Vous devez vous connecter pour publier un commentaire.
Parce que javascript dans un navigateur est mono-thread (sauf pour les web workers qui ne sont pas en cause ici) et un fil d'exécution de javascript s'exécute à la réalisation, avant qu'un autre ne peut s'exécuter, votre déclaration:
sera tout simplement courir pour toujours (ou jusqu'à ce que le navigateur se plaint d'un non-réactif boucle javascript), la page semble être suspendu et aucune autre javascript obtiendrez jamais une chance de s'exécuter, ainsi que le drapeau de la valeur ne peut jamais être changé.
Pour un peu plus d'explications, Javascript est un événement piloté par le langage. Cela signifie qu'il exécute un morceau de Javascript jusqu'à ce qu'il renvoie le contrôle de l'interprète. Alors, seulement quand il revient à l'interprète, Javascript obtient le prochain événement à partir de la file d'attente d'événements et l'exécute.
Toutes choses comme des minuteries et des événements de réseau exécuter par le biais de la file d'attente des événements. Ainsi, lorsqu'un compte à rebours incendies ou d'un réseau demande arrive, il n'a jamais interrompre le cours d'exécution Javascript. Au lieu de cela, un événement est mis dans le code Javascript, des événements de la file d'attente et puis, quand le cours d'exécution Javascript finitions, l'événement suivant est retiré de la file d'attente des événements et il devient à son tour d'exécution.
Donc, quand vous faites une boucle infinie comme
while(flag==false) {}
, actuellement en cours d'exécution Javascript ne se termine jamais et donc le prochain événement n'est jamais sorti de la file d'attente des événements, et donc la valeur deflag
n'est jamais modifié. Ils clé ici est que Javascript n'est pas interruption. Lorsqu'une minuterie se déclenche, il n'interrompt pas le cours d'exécution Javascript, exécuter du Javascript et de laisser ensuite le cours d'exécution Javascript continuer. Il est juste de mettre dans la file d'attente d'événements en attente jusqu'à ce que le cours d'exécution Javascript est fait pour obtenir son tour à exécuter.Ce que vous devez faire est de repenser la façon dont votre code fonctionne et trouver un autre moyen de déclencher le code que vous voulez exécuter lorsque l'
flag
les changements de la valeur. Javascript est un langage événementiel. Donc, ce que vous devez faire est de déterminer quels sont les événements, vous pouvez enregistrer un intérêt dans vous pouvez donc écouter l'événement qui pourrait causer le drapeau pour changer et vous pouvez examiner le drapeau sur cet événement ou vous pouvez déclencher votre propre événement à partir de n'importe quel code peut changer de drapeau ou vous pouvez mettre en œuvre une fonction de rappel que, quel que soit les changements de code que le drapeau pouvez appeler votre rappel à chaque fois que le morceau de code responsable de la modification de la valeur de l'indicateur serait de changer la valeur detrue
, il se contente d'appeler la fonction de rappel et donc votre code que vous voulez exécuter lorsque le drapeau est défini pourtrue
aurez à exécuter au bon moment. C'est beaucoup, beaucoup plus efficace que d'essayer d'utiliser une sorte de minuterie pour vérifier en permanence la valeur de l'indicateur.Javascript est mono-thread, donc la page de blocage de comportement. Vous pouvez utiliser le différé/la promesse de l'approche suggérée par d'autres, mais la façon la plus simple serait d'utiliser
window.setTimeout
. E. g.Voici un bon tutoriel avec de plus amples explications: Tutoriel
MODIFIER
Comme d'autres l'ont souligné, le meilleur moyen serait de re-structurer votre code pour utiliser les callbacks. Cependant, cette réponse devrait vous donner une idée de comment vous pouvez le simuler un comportement asynchrone avec
window.setTimeout
.Utilisation:
Pour itérer sur ($.chacun des objets et de l'exécution d'un assez long est en cours d'exécution (contenant imbriquée ajax synchronisation des appels) sur chaque objet:
J'ai d'abord mis une coutume
done=false
de propriété sur chacun d'eux.Puis, dans une fonction récursive, définissez chaque
done=true
et a continué à l'aide desetTimeout
. (C'est une opération signifiait pour arrêter tous les autres de l'INTERFACE utilisateur, afficher une barre de progression et de bloquer tous les autres donc j'ai pardonné à moi-même pour la synchronisation des appels.)Avec Ecma Script En 2017, Vous pouvez utiliser asynchrone-attendent et alors que ensemble pour faire
Et tout ne va pas planter ou de verrouiller le programme même variable ne jamais être vrai
JS:
Solution à l'aide de Promesse, async\attendent et EventEmitter qui permet de réagir immédiatement sur le drapeau passer sans aucun type de boucles à tous les
EventEmitter
est incorporé dans le nœud. Dans le navigateur, vous devez l'inclure sur votre propre, par exemple à l'aide de cette formule: https://www.npmjs.com/package/eventemitter3ES6 avec Async /Await ,
Solution moderne à l'aide de la Promesse
myFunction()
dans la question d'origine peut être modifié comme suitoù
until()
est cette fonction d'utilitéQuelques références à async/await et la flèche fonctions dans un poste similaire:
https://stackoverflow.com/a/52652681/209794
Similaire à Lightbeard de réponse, j'ai utiliser l'approche suivante
J'ai essayé d'utilisé @Kiran approche comme suit:
(cadre que je suis à l'aide de me forcer à définir les fonctions de cette façon).
Mais sans succès, car lors de l'exécution de venir à l'intérieur checkFlag de fonction deuxième temps,
this
n'est pas mon objet, il estWindow
.Alors, j'ai fini avec le code ci-dessous
JS: