Mongoose, les promises et Q

Mongoose, les promises et Q

Q est un module de promises pour Node.js qui implémente le standard Promises/A+. Il est devenu peu à peu l’implémentation de référence, et de nombreux tutoriaux en présentent différentes fonctionnalités.De même, Mongoose est le module de facto à utiliser lorsqu’on intègre la base MongoDB dans un projet Node.js, ...

Node.js

Q est un module de promises pour Node.js qui implémente le standard Promises/A+. Il est devenu peu à peu l’implémentation de référence, et de nombreux tutoriaux en présentent différentes fonctionnalités.

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:

Conference.findOne({ id: 12 }).exec()
.then (conference) ->
    console.log conference
    next()
, (err) ->
    # handle error here.

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:

Conference.findOne({ id: 12 }).exec()
.then (conference) ->
    console.log conference
    next()
.fail (err) ->
    # handle error here.

La promise renvoyée par Mongoose n’est donc pas directement intégrable avec les promises 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 promise 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:

Q(Conference.findOne({ id: 12 }).exec())
.then (conference) ->
    console.log conference
    next()
.fail (err) ->
    # handle error here.

De façon plus globale, 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 doc 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:

https://github.com/kriskowal/q