J'ai du code qui ressemble à ceci en javascript:
forloop {
//async call, returns an array to its callback
}
Une fois TOUS ces appels asynchrones terminés, je veux calculer le min sur tous les tableaux.
Comment puis-je les attendre tous?
Ma seule idée pour le moment est d'avoir un tableau de booléens appelé done, et de définir done [i] sur true dans la ième fonction de rappel, puis de dire while (tout n'est pas fait) {}
edit: Je suppose qu'une solution possible, mais laide, serait d'éditer le tableau done dans chaque rappel, puis d'appeler une méthode si toutes les autres sont définies à partir de chaque rappel, ainsi le dernier rappel à terminer appellera la méthode continue.
Merci d'avance.
javascript
asynchronous
codeurs
la source
la source
while (not all are done) { }
ne fonctionnerait pas. Pendant que vous attendez occupé, aucun de vos rappels ne peut s'exécuter.Réponses:
Vous n'avez pas été très précis avec votre code, alors je vais inventer un scénario. Supposons que vous ayez 10 appels ajax et que vous vouliez accumuler les résultats de ces 10 appels ajax, puis quand ils ont tous terminé, vous voulez faire quelque chose. Vous pouvez le faire comme ceci en accumulant les données dans un tableau et en gardant une trace de la fin du dernier:
Compteur manuel
Remarque: la gestion des erreurs est importante ici (non affichée car elle est spécifique à la façon dont vous effectuez vos appels ajax). Vous voudrez peut-être réfléchir à la manière dont vous allez gérer le cas où un appel ajax ne se termine jamais, soit avec une erreur, soit bloqué pendant une longue période ou expire après un long moment.
Promesses jQuery
Ajout à ma réponse en 2014. Ces jours-ci, les promesses sont souvent utilisées pour résoudre ce type de problème puisque jQuery's
$.ajax()
retourne déjà une promesse et vous$.when()
fera savoir quand un groupe de promesses sont toutes résolues et collectera les résultats de retour pour vous:Promesses standard ES6
Comme spécifié dans la réponse de kba : si vous avez un environnement avec des promesses natives intégrées (navigateur moderne ou node.js ou utilisant babeljs transpile ou utilisant un promesse polyfill), vous pouvez utiliser les promesses spécifiées par ES6. Consultez ce tableau pour la prise en charge du navigateur. Les promesses sont prises en charge dans à peu près tous les navigateurs actuels, à l'exception d'IE.
Si
doAjax()
retourne une promesse, vous pouvez le faire:Si vous avez besoin de transformer une opération asynchrone sans promesse en une opération qui renvoie une promesse, vous pouvez la «promettre» comme ceci:
Et, puis utilisez le modèle ci-dessus:
Promesses Bluebird
Si vous utilisez une bibliothèque plus riche en fonctionnalités, telle que la bibliothèque de promesses Bluebird , elle possède des fonctions supplémentaires intégrées pour vous faciliter la tâche:
la source
doAjax()
qui retourne une promesse comme l'une des options. Même chose quefetch()
.Arrivée à partir de 2015: nous avons maintenant des promesses natives dans le navigateur le plus récent (Edge 12, Firefox 40, Chrome 43, Safari 8, Opera 32 et navigateur Android 4.4.4 et iOS Safari 8.4, mais pas Internet Explorer, Opera Mini et les versions antérieures d'Android).
Si nous voulons effectuer 10 actions asynchrones et être notifié lorsqu'elles sont toutes terminées, nous pouvons utiliser le natif
Promise.all
, sans aucune bibliothèque externe:la source
Promises.all()
devrait êtrePromise.all()
.Promise.all()
dans lesquels aucune version actuelle d'IE.Vous pouvez utiliser l' objet Deferred de jQuery avec la méthode when .
la source
jQuery
ce qui signifie généralement que l'OP ne voulait pas de réponse jQuery.Vous pouvez l'émuler comme ceci:
puis chaque appel asynchrone fait ceci:
tandis que dans chaque rappel asynchrone à la fin de la méthode, vous ajoutez cette ligne:
En d'autres termes, vous émulez une fonctionnalité de comptage à rebours.
la source
C'est la manière la plus soignée à mon avis.
Promise.all
FetchAPI
(pour une raison quelconque, Array.map ne fonctionne pas dans les fonctions .then pour moi. Mais vous pouvez utiliser un .forEach et [] .concat () ou quelque chose de similaire)
la source
return responses.map(response => { return response.json(); })
, oureturn responses.map(response => response.json())
.Utilisez une bibliothèque de flux de contrôle comme
after
la source