web-dev-qa-db-fra.com

Koa / Co / Bluebird ou Q / Generators / Promises / Thunks interplay? (Node.js)

J'envisage de créer une application Web en partie avec Koa, mais je ne sais pas vraiment comment, comment et pourquoi choisir entre - et appliquer - la gamme de technologies/approches de soutien facilitant l'asynchronisation ( énumérés ci-dessous).

Dans l'ensemble, les orientations disparates sur le Web à ce sujet laissent encore les choses floues, en particulier en ce qui concerne l'évolution des meilleures pratiques, ou du moins les meilleures, et dans quels scénarios. Il semble qu'il y ait peu ou rien sur le Web qui remette tout cela en contexte.

J'espère que les réponses à ce message tentaculaire au gros cul pourront corriger cela . Peut-être que les questions ci-dessous peuvent inspirer quelqu'un à écrire un article de blog complet ou similaire pour aborder cette question. Mon sentiment est que je ne suis même pas proche du seul qui en bénéficierait.

Je serais donc heureux si la communauté brillante pouvait aider à répondre et à clarifier les questions suivantes concernant les technologies énumérées ci-dessous (en gras):

- a) Comment et dans quelles circonstances (le cas échéant) sont-ils complémentaires, suppléments, substituts et/ou solutions qui se chevauchent?

- b) Quels sont leurs compromis en termes de vitesse, de facilité de traitement des erreurs et de facilité de débogage?

- c) Quand, où et pourquoi peut-il être préférable d'utiliser "cette" contre "cette" technologie, combinaison de technologies et/ou approche?

- d) Quelles technologies ou approches, le cas échéant, peuvent être des "étoiles à gradation".

(En espérant que les opinions qui font partie des réponses peuvent être bien expliquées.)

==============================

Les technologies:

* Koa *

Ma compréhension:

Koa est une base minimale pour construire des applications Node destinées à tirer parti des fonctionnalités ECMAScript-6, une fonctionnalité en particulier étant les générateurs.

* Co *

Ma compréhension:

- Co est une bibliothèque d'utilitaires pour exécuter les générateurs ECMAScript-6 (qui sont natifs de Node .011 harmonie), dans le but d'alléger une partie/beaucoup (?) Du besoin d'écrire code passe-partout pour faire fonctionner et gérer les générateurs.

- Co fait intrinsèquement partie de Koa (?).

Questions spécifiques:

- Si et comment utiliser Co différemment dans Koa que dans un contexte non-Koa. En d'autres termes, Koa façonne-t-il entièrement Co?

- Co pourrait-il être remplacé dans Koa par une autre bibliothèque de générateur similaire s'il y en a/était une meilleure? Y a-t-il?

* Bibliothèques Promise telles que "Q" et Bluebird *

Ma compréhension:

- Ils sont en quelque sorte des "polyfills" pour implémenter la spécification Promises/A +, si et jusqu'à Node exécute nativement cette spécification.
- Ils ont d'autres utilitaires non spécifiés pour faciliter les promesses d'utilisation, tels que l'utilitaire promisfyAll de Bluebird.

Questions spécifiques:

- Ma compréhension est que la spécification ECMAScript-6 reflète/reflètera largement la spécification Promises/A +, mais même ainsi, Node 0.11v l'harmonie n'implémente pas nativement Promises. (Est-ce correct?) Cependant, dans ce cas, des technologies telles que Q et Bluebird seront-elles en voie de disparition?

- J'ai lu quelque chose à l'effet que "Q" et Bluebird supportent les générateurs. Qu'est-ce que ça veut dire? Cela signifie-t-il en partie que, par exemple, ils ont dans une certaine mesure fourni la même utilité que Co, et si oui, dans quelle mesure?

* Thunks and Promises *

Je pense que j'ai une bonne idée de ce qu'ils sont, mais en espérant que quelqu'un puisse fournir une définition succincte et claire de la hauteur de l'ascenseur sur ce que chacun est, et bien sûr, comme demandé ci-dessus, pour expliquer quand utiliser l'un par rapport à l'autre - dans un contexte Koa et non dans celui-ci.

Questions spécifiques:

- Avantages et inconvénients d'utiliser quelque chose comme Bluebird's promisfy, par opposition à l'utilisation de Thunkify (github com/visionmedia/node-thunkify)?

==============================

Pour donner un peu plus de contexte à cet article et à ses questions , il pourrait être intéressant de discuter et de contraster les techniques de Koa présentées dans les pages Web suivantes (en particulier sur sur une base avantages vs inconvénients):

- a) www.marcusoft. net/2014/03/koaintro.html (Où sont les thunks ou les promesses, ou est-ce que je ne vois rien?)

- b) boucle forte. com/strongblog/node-js-express-introduction-koa-js-zone (Encore une fois, où sont les thunks ou les promesses?)

- c) github. com/koajs/koa/blob/master/docs/guide.md (À quoi correspond l'argument "next", et qu'est-ce qui le définit et où?)

- d) blog.peterdecroos. com/blog/2014/01/22/javascript-generators-first-impressions (Pas dans un contexte Koa, mais présente l'utilisation de Co avec une bibliothèque de promesses (Bluebird), donc je suppose que la technique/le modèle présenté ici se prête lui-même à l'utilisation dans Koa (?). Si oui, alors comment bien?

Merci a tous!

60
JLS

Je travaille presque intensivement avec les générateurs depuis un mois maintenant, alors je peux peut-être essayer. Je vais essayer de garder les opinions au minimum. Espérons que cela aide à clarifier une partie de la confusion.

Une partie de la raison du manque de meilleures pratiques et de meilleures explications est que la fonctionnalité est encore si nouvelle en javascript. Il y a encore très peu d'endroits où vous pouvez utiliser les générateurs node.js et firefox étant les plus importants, bien que firefox s'écarte un peu de la norme.

Je voudrais noter qu'il existe des outils comme traceur et régénérateur qui vous permettront de les utiliser pour le développement et vous permettront de les transformer en ES5 semi-équivalent, donc si vous trouvez agréable de travailler avec eux, il n'y a aucune raison de ne pas commencer à les utiliser à moins que vous ciblez des navigateurs archaïques.

Générateurs

Les générateurs n'étaient pas initialement considérés comme un moyen de gérer les flux de contrôle asynchrones, mais ils fonctionnent à merveille. Les générateurs sont essentiellement des fonctions d'itérateur qui permettent de suspendre et de reprendre leur exécution grâce à l'utilisation de yield.

Le mot-clé yield indique essentiellement de renvoyer cette valeur pour cette itération et je reprendrai là où je me suis arrêté lorsque vous appellerez à nouveau next () sur moi.

Les fonctions de générateur sont des fonctions spéciales en ce sens qu'elles ne s'exécutent pas la première fois qu'elles sont appelées, mais renvoient à la place un objet itérateur avec quelques méthodes et la possibilité d'être utilisé dans des boucles for-of et des compréhensions de tableaux.

send (),: Ceci envoie une valeur dans le générateur la traitant comme la dernière valeur de rendement et continue l'itération suivante

next () ,: Ceci continue la prochaine itération du générateur

throw (): Cela lève une exception dans le générateur, ce qui provoque le générateur de lever l'exception comme si elle provenait de la dernière instruction yield.

close (): Cela force le générateur à retourner l'exécution et appelle tout code finalement du générateur qui permet de déclencher la gestion finale des erreurs si nécessaire.

Leur capacité à faire une pause et à reprendre est ce qui les rend si puissants pour gérer le contrôle de flux.

Co

Co a été construit autour de la capacité des générateurs à faciliter le contrôle du flux de manipulation. Il ne prend pas en charge toutes les choses que vous pouvez faire avec les générateurs, mais vous pouvez utiliser la plupart d'entre eux grâce à leur utilisation avec moins de passe-partout et de maux de tête. Et à des fins de contrôle de flux, je n'ai pas trouvé que j'avais besoin de quelque chose en dehors de ce que co fournit déjà. Bien que pour être honnête, je n'ai pas essayé d'envoyer une valeur dans un générateur pendant le contrôle de flux, mais cela soulève des possibilités intéressantes ....

Il y a d'autres bibliothèques de générateurs là-bas, certaines d'entre elles que je peux penser du haut de ma tête sont suspendues et générées. Je les ai tous essayés et co offre le plus de flexibilité. La suspension peut être un peu plus facile à suivre si vous n'êtes pas encore habitué aux générateurs, mais je ne peux pas le dire avec autorité.

En ce qui concerne les nœuds et les meilleures pratiques, je dirais que co gagne actuellement haut la main avec la quantité d'outils de support qui ont été créés pour l'accompagner. Avec suspendre le runner le plus probable.

Co fonctionne avec les promesses et les thunks et ils sont utilisés pour la déclaration de rendement afin que co sache quand continuer l'exécution du générateur au lieu de devoir manuellement appeler next (). Co prend également en charge l'utilisation de générateurs, de fonctions de générateur, d'objets et de tableaux pour une prise en charge supplémentaire du contrôle de flux.

En produisant un tableau ou un objet, vous pouvez faire co-exécuter des opérations parallèles sur tous les éléments générés. En cédant à un générateur ou à une fonction de générateur, Co déléguera d'autres appels au nouveau générateur jusqu'à ce qu'il soit terminé, puis reprendra l'appel suivant sur le générateur actuel, vous permettant de créer efficacement des mécanismes de contrôle de flux très intéressants avec un code passe-partout minimal.

Promesses

Alors que je disais que je garderais les opinions au minimum, je voudrais dire que pour moi, les promesses sont probablement le concept le plus difficile à comprendre. Ils sont un outil puissant pour maintenir le code mais ils sont difficiles à saisir le fonctionnement interne de et peuvent être accompagnés de quelques pièges s'ils sont utilisés pour un contrôle de flux avancé.

La façon la plus simple à laquelle je peux penser pour expliquer les promesses est qu'il s'agit d'un objet renvoyé par une fonction qui maintient l'état de la fonction et une liste de rappels à appeler lorsque l'état spécifique de l'objet est ou a été entré.

La promesse que les bibliothèques elles-mêmes n'iront pas de sitôt. Ils ajoutent beaucoup de Nice aux nantis pour les promesses incluses done () qui ne sont pas entrées dans la spécification ES6. Sans parler du fait que les mêmes bibliothèques peuvent être utilisées sur le navigateur et dans le nœud, nous les aurons pendant longtemps.

Thunks

Les thunks ne sont que des fonctions qui prennent un rappel de paramètre unique et retournent une autre fonction qu'ils encapsulent.

Cela crée une fermeture qui permet au code appelant d'instancier la fonction passant dans son rappel afin qu'il puisse être informé lorsque la méthode est terminée.

Les Thunks sont assez simples à comprendre et à utiliser à mon avis, mais ils ne sont pas le bon outil pour tout. Par exemple, la réapparition est une douleur majeure pour laquelle créer un thunk, vous pouvez le faire mais ce n'est pas facile.

Thunks vs Promises

Ceux-ci ne s'excluent pas mutuellement et peuvent facilement être utilisés ensemble, mais il est généralement préférable pour votre raison d'en choisir un et de s'y tenir. Ou, à tout le moins, choisissez une convention afin de savoir facilement laquelle est laquelle. Thunks fonctionne plus vite d'après mon expérience, mais je ne l'ai pas comparé. La plupart de ceci est probablement parce que c'est une abstraction plus petite et n'a pas de mécanismes de gestion des erreurs intégrés.

Cependant, vous construirez généralement quelque chose qui nécessite une gestion des erreurs, de sorte que les gains de performances globaux des thunks pourraient facilement égaliser ou favoriser les promesses en fonction de votre code.

Quand utiliser

Générateurs - Lorsque vous pouvez dire en toute sécurité que votre application pourra s'exécuter sur le Edge qui saigne, que ce soit Firefox uniquement pour le navigateur ou le nœud> 0.11.3

Je les utilise beaucoup dans l'entreprise où je suis maintenant et je ne pourrais pas être plus satisfait des mécanismes de contrôle des flux et de l'évaluation paresseuse qu'ils permettent.

Promesses vs Thunks - Cela dépend vraiment de vous et de la façon dont vous travaillez avec chacun. Ils n'offrent pas les mêmes avantages et ne résolvent pas le même problème. Les promesses aident à traiter directement le problème asynchrone, les thunks s'assurent simplement qu'une fonction prend le paramètre de rappel nécessaire pour que d'autres codes passent.

Vous pouvez les utiliser à la fois ensemble et aussi longtemps que vous pouvez les conserver afin qu'il soit évident de savoir lequel ne vous posera pas de problème.

Promesses/Thunks avec les générateurs - Je suggère de le faire chaque fois que vous utilisez des générateurs pour le flux de contrôle. Ce n'est pas nécessaire, mais c'est plus facile, tout comme l'utilisation de co comme abstraction pour contrôler le flux avec des générateurs est plus facile. Moins de code à taper, une maintenance plus facile et moins de possibilités de toucher un cas Edge que quelqu'un d'autre n'a pas encore rencontré.

Koa

Je ne vais pas entrer dans beaucoup de détails sur le koa. Il suffit de dire que c'est similaire à express mais écrit pour profiter des générateurs. Cela lui donne des avantages uniques tels qu'une gestion des erreurs plus facile et un middleware en cascade. Il y avait des façons d'accomplir toutes ces tâches auparavant, mais elles n'étaient pas élégantes et parfois pas les plus performantes.

Remarque spéciale: les générateurs ouvrent une porte de possibilités que nous n'avons vraiment pas encore explorées. Tout comme ils peuvent être utilisés pour contrôler le flux lorsque ce n'était pas leur conception initiale, je suis certain qu'ils peuvent être utilisés pour résoudre de nombreux autres problèmes avec lesquels nous avons normalement des problèmes en javascript. Ce seront probablement des esprits plus brillants que moi qui découvriront comment les utiliser autrement, mais je commencerais au moins à jouer avec eux et à mieux comprendre ce dont ils sont capables. Il y a encore plus de goodies pour les générateurs à venir dans ES.next.

54
Thot