Asynchrone pour le cycle en JavaScript
J'ai besoin d'une boucle qui attend un appel asynchrone avant de continuer. Quelque chose comme:
for ( /* ... */ ) {
someFunction(param1, praram2, function(result) {
//Okay, for cycle could continue
})
}
alert("For cycle ended");
Comment pourrais-je faire cela? Avez-vous des idées?
- Wow
( /* ... */ )
ressemble à un monstre et j'ai peur maintenant 🙁
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas mélanger synchrone et asynchrone en JavaScript si vous bloquez le script, vous pouvez bloquer le Navigateur.
Vous devez aller au complet de la manifestation, pilotée par ici, heureusement, nous ne pouvons cacher le vilain de choses.
EDIT: mise à Jour du code.
Ce sera notre asynchrone
loop
, vous pouvez bien sûr modifier encore plus loin pour prendre par exemple une fonction pour vérifier la condition de la boucle etc.Maintenant sur le test:
Et la sortie:
loop.break()
est censé être en train de faire? Juste une manière de force si vous voulez?J'ai simplifié le présent:
FONCTION:
UTILISATION:
EXEMPLE: http://jsfiddle.net/NXTv7/8/
Une alternative plus propre à ce que @Ivo a suggéré une Méthode Asynchrone de la File d'attente, en supposant que vous avez seulement besoin de faire un appel asynchrone pour la collection.
(Voir ce post par Dustin Diaz pour une explication plus détaillée)
Il vous suffit de créer une nouvelle instance de
Queue
, ajouter les rappels que vous avez besoin, puis vider la file d'attente avec l'async réponse.Un avantage de ce modèle est que vous pouvez ajouter plusieurs fonctions à la file d'attente au lieu d'un seul.
Si vous avez un objet qui contient des fonctions iterator, vous pouvez ajouter le support pour cette file d'attente derrière les coulisses et d'écrire un code qui ressemble synchrone, mais n'est-ce pas:
simplement écrire
each
pour mettre la fonction anonyme dans la file d'attente au lieu de l'exécuter immédiatement, puis vider la file d'attente lors de votre appel asynchrone est terminée. C'est très simple et puissant motif de conception.P. S. Si vous utilisez jQuery, vous avez déjà une méthode asynchrone de la file d'attente à votre disposition appelé jQuery.Différé.
someFunction
, qui retardent le reste de la boucle, votre modèle définit une liste de fonctions qui seront exécutés dans l'ordre et recevront les résultats de un autre appel de fonction. C'est un bon motif, mais je ne pense pas que cela correspond à la question en cause.setTimeout
. Vous risquez de comportement involontaire si le code est exécuté plus rapidement que vous pouvez anticiper.setTimeout
que si la fonction de rappel ne prend que la moitié du temps, bien que le code s'exécute plus vite encore... alors, quel est le point? Le "code" dans la "boucle" est toujours dans l'ordre, si vous faites quelques choses à l'extérieur de l'avant de la remplir de rappel vous êtes déjà demandé que des ennuis, mais de nouveau, c'est mono-thread, j'ai un moment difficile à venir avec un scénario oùsetTimeout
de casser quelque chose, sans plus de mauvaise conception.setTimeout
. Se sent comme un hack. J'ai regardé à votre exemple, pendant plusieurs minutes, et je ne suis toujours pas clair sur ce qu'il fait. Quand je tombe sur un code comme celui de mon travail, je le remplacer.Aussi regarder cette magnifique bibliothèque caolan /async. Votre
for
boucle peut être réalisé facilement à l'aide de mapSeries ou série.Je pouvais poster un exemple de code si votre exemple avoir plus de détails en elle.
Nous pouvons aussi utiliser l'aide de jquery.Différé. dans ce cas asyncLoop fonction devrait ressembler à ceci:
la fonction de rappel doit ressembler à cela:
exemple de fonction qui résout différé:
J'ai été en utilisant le "setTimeout(Func,0);" astuce pour environ un an. Voici certains travaux de recherche récents que j'ai écrit jusqu'à expliquer comment l'accélérer un peu. Si vous voulez juste la réponse, passez à l'Étape 4. Étape 1 2 et 3 expliquer le raisonnement et la mécanique;
Donné asynchrone travailleur fonction
someFunction
qui va rappeler un résultat de fonction avec unresult
argument de dire si oui ou non la boucle doit se poursuivre:Afin de vérifier si oui ou non à la fin de la boucle, le travailleur de la fonction
someFunction
peut transmettre le résultat de la fonction à d'autres opérations asynchrones. Aussi, l'expression peut être encapsulé dans une fonction asynchrone en prenant une fonctiondone
que le rappel.Si vous aimez wilsonpage de la réponse, mais sont plus habitués à l'utilisation de async.js's de la syntaxe, voici une variante:
Démo peut être trouvée ici - http://jsfiddle.net/NXTv7/8/
Voici un autre exemple qui, je pense, est plus lisible que les autres, où vous enveloppez votre asynchrone en fonction à l'intérieur d'une fonction qui prend en
done
fonction, l'actuel indice de boucle, et le résultat (le cas échéant) de l'ancien appel asynchrone:Une fois
done()
est invoquée, elle déclenche le prochain appel asynchrone, passant à nouveau dans le fait de la fonction, l'indice courant et résultat précédent. Une fois la totalité de la boucle est terminée, la condition de la bouclecallback
sera invoquée.Voici un extrait de code que vous pouvez exécuter:
JS:
Vous pouvez utiliser
async await
introduit dans l'ES7:Cela ne fonctionne que si
someFunction
est de retour une Promesse!Si
someFunction
n'est pas le retour d'une Promesse, alors vous pouvez le faire revenir une Promesse par vous-même comme ceci:Puis remplacez cette ligne
await someFunction(param1, param2);
parawait asynSomeFunction(param1, param2);
S'il vous plaît comprendre Promesses avant d'écrire
async await
code!Unexpected await inside loop
.javascript
question. Cet avertissement vient de votreeslint
de configuration. J'ai toujours désactiver cette règle deeslint
parce que dans la plupart des endroits que j'ai vraiment besoin d'attendre à l'intérieur de la bouclehttp://cuzztuts.blogspot.ro/2011/12/js-async-for-very-cool.html
EDIT:
lien à partir de github: https://github.com/cuzzea/lib_repo/blob/master/cuzzea/js/functions/core/async_for.js
Cette fonction permet de créer un pour cent pause dans la boucle à l'aide de paramètres.de limite. La limite de propriété est juste un entier, mais lorsqu'il est réglé sur tableau.longueur * 0.1, ce seront les paramètres.limit_callback d'être appelé toutes les 10%.
exemple:
Une promesse, basé sur la bibliothèque solution:
J'ai besoin d'appeler certaines fonctions asynchrones
X
fois, à chaque itération, il s'est passé après la précédente a été fait, j'ai donc écrit un petite bibliothèque qui peut être utilisée comme ceci:Chaque fois que définis par l'utilisateur fonction de boucle est appelée, elle a deux arguments, l'itération de l'index et de l'appel précédent de la valeur de retour.
Ceci est un exemple de sortie: