2012-02-22 4 views
18

Je sais qu'il y a beaucoup control flow libraries pour node.js. Certains d'entre eux permettent à une chaîne async de fonctionner avec des rappels (comme async, asyncblock, etc), les autres utilisent promise concept (Q, différée, futures, etc.). Compte tenu d'un script long terme faisant une série d'actions les unes après les autres qui peuvent échouer à tout moment, quel flux de contrôle préférez-vous et pourquoi? Quels sont les avantages et inconvénients?Flux de contrôle Node.js: rappels ou promesses?

Répondre

5

Je ne pense pas qu'il existe de nombreux avantages et inconvénients. Async est très populaire (basé sur npm packages that depend on it). J'aime les bibliothèques de flux de contrôle (spécifiquement async), parce que c'est plus facile à comprendre pour moi. Les promesses me troublent, tandis que l'async est facilement compréhensible. Je soupçonne que c'est juste une chose de la courbe d'apprentissage, et les promesses seraient plus lisibles si je dépensais l'effort pour les apprendre. Mais devrais-je m'attendre à ce que des gens essayent de lire mon code aussi? Il existe également un troisième type: Fibers. Fibres ne fonctionne pas encore sous Windows, mais (IMO) offre la syntaxe la plus claire pour les choses qui doivent être exécutées en série.

13

Pros pour callbacks:

  • simple à comprendre et à créer.
  • Plus légèrement plus efficace, car moins d'objets sont créés et garbage collectés.
  • Le nœud a opté pour (error,result) dans l'ensemble des rappels. Je recommande de suivre leur ordre d'argument pour la cohérence. (Par opposition à dire (result1, result2, result3, error).)

Plus de promesses:

  • Fournit une interface fluide , ce qui peut parfois aider à atténuer l'enfer de rappel imbriqué, comme shown here. Le code semble circuler linéairement en enchaînant .then(foo).then(bar) appels.
  • Une bibliothèque de bonnes promesses vous permettra d'exécuter de nombreuses opérations asynchrones en parallèlement, et de continuer seulement quand elles sont toutes terminées. La bibliothèque Deferred le fait de façon transparente à travers map, Q a allResolved, et les promesses ES6 offrent Promise.all(). Une bibliothèque de bonnes promesses vous permet de spécifier une fonction de gestion d'erreur qui sera appelée si l'une des fonctions mises en file d'attente échoue. Pour faire cela avec des rappels, il faut un peu d'information: if (err) return callback(err); au début de chaque rappel.

Il serait logique d'utiliser callbacks près du fond de la pile, pour le code qui sera exécuté plusieurs fois par seconde. Plus haut dans la pile, les promesses peuvent être préférables car elles sont plus faciles à lire et à comprendre, et peuvent gérer les erreurs plus élégamment.

Il est à noter que les promesses peuvent être générées à partir des rappels lors de l'exécution. Ainsi, vous pouvez implémenter votre code de base dans le formulaire de rappel minimaliste, et toujours exposer une version promise de la bibliothèque si vous le souhaitez. (Comme dans Q.nfbind().)

Je serais intéressé d'entendre d'autres avantages/inconvénients.

Astuce supplémentaire: Toujours gérer les erreurs! Avec les deux méthodes, si vous ne gérez pas l'erreur, elle disparaîtra tout simplement, vous laissant dans l'ignorance de la raison pour laquelle votre code n'a pas fonctionné comme prévu.

Les rappels doivent toujours gérer if (err) ... et Promises doit toujours avoir un .catch() s'ils ne retournent pas.

Même si vous vous attendez parfois à des erreurs et que vous n'avez pas besoin de les gérer, ne pas gérer les erreurs inattendues signifie que vous n'entendrez pas parler d'erreurs de développeur telles que des fautes de frappe.

Une alternative à .catch() pour Promises est d'écouter unhandled rejections. Personnellement, je l'utilise pour émettre un avertissement que .catch() était manquant!

+1

En savoir plus sur perfs: http://thanpol.as/javascript/promises-a-performance-hits-you-should-be-aware-of/ – Offirmo

+0

lien ne fonctionne plus – Shide

+1

Voici [une copie archivée de Le lien perf d'Offirmo] (http://web.archive.org/web/20160522044854/http://thanpol.as/javascript/promises-a-performance-hits-you-should-be-aware-of). – joeytwiddle

0

J'ai expérimenté avec une approche déclarative avec cette bibliothèque: http://chainsjs.org encore plus de travail à faire là-dessus, mais il vous donne la possibilité de définir une « carte d'exécution » où vous pouvez à peu près complètement contrôler le flux d'exécution à partir d'une cartographie simple.

+0

Ce site était en panne aujourd'hui mais j'ai trouvé [une copie] (http://web.archive.org/web/20141217011058/http://chainsjs.org/) dans l'archive. Il existe une liste d'autres bibliothèques de flux de contrôle [ici] (https://github.com/joyent/node/wiki/modules#user-content-wiki-async-flow). – joeytwiddle

+0

@joeytwiddle - merci pour la note, je n'ai jamais changé l'adresse IP lorsque les pages github changé IP. Je viens de mettre à jour DNS, il devrait être de retour bientôt. –

Questions connexes