Il y a 8 ans -
Temps de lecture 1 minute
Mongoose, les promises et Q

De même, Mongoose est le module de facto à utiliser lorsqu’on intègre la base MongoDB dans un projet Node.js, puisqu’il est supporté officiellement par MongoDB, Inc.
Depuis quelques temps maintenant, le module Mongoose propose le support des Promises en plus de son fonctionnement via callback via l’appel de la fonction exec. C’est à dire, qu’il est possible d’écrire :
[javascript gutter= »true »]Conference.findOne({ id: 12 }).exec()
.then (conference) ->
console.log conference
next()
, (err) ->
# handle error here.[/javascript]
Malheureusement, l’implémentation des Promises utilisées par Mongoose n’est pas compatible avec l’implémentation Q. Notamment, il n’est pas possible d’utiliser la fonction fail, et d’écrire le code précédent de la façon suivante :
[javascript gutter= »true »]Conference.findOne({ id: 12 }).exec()
.then (conference) ->
console.log conference
next()
.fail (err) ->
# handle error here.[/javascript]
La promesse renvoyée par Mongoose n’est donc pas directement intégrable avec les promesses Q. On peut donc penser qu’il est compliqué d’intégrer les deux types de Promises.
Heureusement Q propose une solution simple pour les intégrer avec la fonction Q() qui permet de wrapper une promise Mongoose dans une promesse Q, et donc d’intégrer les Promises Mongoose dans des chaînages de promises Q, ou bien d’utiliser tout simplement les syntaxes Q.
Ainsi, vous devrez écrire le code suivant :
[javascript gutter= »true »]Q(Conference.findOne({ id: 12 }).exec())
.then (conference) ->
console.log conference
next()
.fail (err) ->
# handle error here.[/javascript]
Plus généralement, si vous travaillez avec une autre librairie de Promises que Q, vous pouvez wrapper vos Promises avec la fonction Q() dans la mesure où votre librairie propose une syntaxe compatible avec les wrappers Q. Dixit la documentation de la librairie :
Q can exchange promises with jQuery, Dojo, When.js, WinJS, and more
Pour aller plus loin
La homepage GitHub de la librairie Q et sa documentation:
Commentaire
5 réponses pour " Mongoose, les promises et Q "
Published by yves amsellem , Il y a 8 ans
Il me semble que bluebird (http://goo.gl/eSdUw5) a remplacé Q au rang de librairie de Promises de référence. Notamment en raison de ses performances — sans overhead avec les callbacks classiques — et sans commune mesure avec Q (http://goo.gl/wPPQhc).
Un bel article — Why I am switching to promises — de fin 2013 présente le sujet et produit des tests de performances indépendants (http://goo.gl/7S4ESk).
Published by Alexis Kinsella , Il y a 8 ans
Un autre article sur Bluebird arrive cette semaine (Vendredi en principe), il référence justement les deux liens que tu indiques :) « Why I am switching to promises » est en effet un article très intéressant. C’est grâce à cet article que j’ai découvert Bluebird … et Zalgo ;)
Published by Bocker , Il y a 8 ans
Merci pour cet article.
Pourriez vous me donner des examples pour le chaînage de plusieurs requêtes mongoose?
Je ne vois pas comment il faut les imbriquer,
merci d’avance
Published by Alexis Kinsella , Il y a 8 ans
Etant donné que nous encapsulons les accès Mongoose avec Q (Ou bien avec Bluebird), nous pouvons utiliser les méthodes de chainage proposées par les librairies de promesse citées. Par exemple, nous pouvons écrire le code suivant:
Q(Conference.findOne({ id: 12 }).exec()).then((conference) -> {
console.log(conference);
return someWebHook.call(conference);
}).then((result) -> {
console.log result
}).fail((err) -> {
# handle error here.
})
Dans ce premier cas, en considérant que l’appel au web hook renvoie également une promesse, la seconde promesse sera appelée si la première est en succès. Par contre, il n’est pas possible dans le second ‘then’ d’accéder à la variable conférence. Si le besoin s’en fait sentir, il est possible d’écrire le code précédent un peu différemment pour accéder à la variable « conference »:
Q(Conference.findOne({ id: 12 }).exec())
.then((conference) -> {
console.log(conference)
return someWebHook.call(conference).then((result) -> { console.log(result); }
}).fail((err) -> {
# handle error here.
})
Published by Alexis Kinsella , Il y a 8 ans
Dur, dur l’absence d’indentation dans les commentaires …