comment utiliser q.js promet de travailler avec plusieurs opérations asynchrones
Remarque: Cette question est aussi de la croix-posté dans Q. js liste de diffusion de plus de ici.
j'ai eu une situation avec plusieurs opérations asynchrones et la réponse que j'ai accepté a souligné que l'aide de Promesses à l'aide d'une bibliothèque, tel que q.js serait plus bénéfique.
Je suis convaincu de revoir mon code pour utiliser des Promesses, mais parce que le code est assez long, j'ai coupé la pertinence des portions et exportés sur les éléments essentiels dans un autre repo.
Les pensions de titres sont ici et le fichier le plus important est cette.
L'exigence est que je veux pageSizes non vide, après avoir traversé tous les traîné'n fichiers perdus.
Le problème est que le FileAPI des opérations à l'intérieur getSizeSettingsFromPage fonction provoque getSizeSettingsFromPage être asynchrone.
Donc je ne peut pas placer checkWhenReady(); comme ça.
function traverseFiles() {
for (var i=0, l=pages.length; i<l; i++) {
getSizeSettingsFromPage(pages[i], calculateRatio);
}
checkWhenReady(); //this always returns 0.
}
Cela fonctionne, mais ce n'est pas l'idéal. Je préfère l'appeler checkWhenReady juste une FOIS, après toutes les pages
ont subi cette fonction calculateRatio avec succès.
function calculateRatio(width, height, filename) {
//.... code
pageSizes.add(filename, object);
checkWhenReady(); //this works but it is not ideal. I prefer to call this method AFTER all the `pages` have undergone calculateRatio
//..... more code...
}
Comment puis-je refactoriser le code à utiliser des Promesses dans Q. js?
Vous devez vous connecter pour publier un commentaire.
Mes suggestions pour obtenir ce travail à Q. js sont ci-dessous. La clé est que chaque fois que vous voulez faire quelque chose de manière asynchrone, vous devez retourner une promesse, et une fois la tâche terminée, vous devez résoudre cette promesse. Qui permet à l'appelant de la fonction permettant d'écouter de la tâche à effectuer, puis faire autre chose.
Comme avant, j'ai commenté mes changements avec
//***
. Laissez-moi savoir si vous avez d'autres questions.Modifier
defer
crée un Différés, qui contient deux parties, unepromise
et laresolve
fonction. Lepromise
est retourné pargetSizeSettingsFromPage
. Fondamentalement, le retour d'une promesse est une façon pour fonction de dire "je vais revenir à vous plus tard." Une fois que la fonction est terminée, il est de la tâche (dans ce cas, une fois laimage.onload
événement a été déclenché) leresolve
fonction est utilisée pour régler la promesse. Qui indique à quoi que ce soit en attente sur la promesse que la tâche a été achevée.Voici un exemple plus simple:
La
addAsync
fonction ajoute deux nombres, mais il attend 2 secondes avant de les ajouter. Depuis, il est asynchrone, il renvoie une promesse (deferred.promse
) et décide de la promesse, après les 2 secondes d'attente (deferred.resolve
). Lethen
méthode peut être appelée sur une promesse et a adopté une fonction de callback à exécuter après la promesse a été résolu. La fonction de rappel est passé dans la résolution de la valeur de la promesse.Dans votre cas, nous avons eu un tableau de promesses et nous avons dû attendre pour tous de leur être fait avant l'exécution d'une fonction, nous avons donc utilisé Q. tous les. Voici un exemple:
defer
, ainsi que quelques autres choses. Cheers 🙂getSizeSettingsFromPage
appelercalculateRatio
sans le besoin de passer dans lewhenReady
paramètre. Aussi longtemps que vous êtes à l'aide de promesses, vous pourriez aussi bien aller tout le chemin :-). Les promesses d'éliminer la nécessité pour ces types de rappels.Q
s'readme. Pour l'instant il semble assumer trop de familiarité avec l'idée de promesses. Vous pourriez peut-être modifier et soumettre une demande d'extraction?:D
Ressemble, vous devez utiliser le
Q.all
fonction pour créer un master promesse correspondant à quand tous les getSizeSettings promesses sont fufilled.https://github.com/kriskowal/q#combination
La plupart promettent les bibliothèques devraient fournir une méthode similaire pour faire ce genre de synchronisation. Si jamais vous tombez sur celui qui n'est pas ce que vous pourriez faire est de crochet de chaque promesse d'un rappel qui s'incrémente d'un partagées compteur lorsqu'elle est appelée. Lorsque votre compteur atteint
n
vous savez que vous avez déjà résolu, toutes les promesses de sorte que vous pouvez avoir le incrementor rappel appeler le "réel" de rappel ainsi.Noter que dans ces cas jusqu'à présent, les appels asynchrones sont autorisées à s'exécuter en parallèle. Si vous en avez besoin pour exécuter séquentiellement ensuite, généralement, le seul moyen est de réécrire la boucle for comme une fonction récursive