Publié par

Il y a 5 ans -

Temps de lecture 1 minute

Mongoose, les promises et Q

Q est un module de Promises (promesses en français) 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 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 :

 

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

 

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:

https://github.com/kriskowal/q

Publié par

Publié par Alexis Kinsella

Alexis Kinsella est un consultant Xebia passionné aussi bien par les problématiques frontend (web et mobile) que backend. Après de longues années passées sur les technologies Java, Alexis a fait d'iOS, Node.js et du Cloud ( AWS Certified Solutions Architect - Associate ) ses nouveaux terrains d'expérimentation lui permettant d'explorer les architectures web et mobiles ainsi que leurs problématiques associées.

Commentaire

5 réponses pour " Mongoose, les promises et Q "

  1. Publié par , Il y a 5 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).

  2. Publié par , Il y a 5 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 ;)

  3. Publié par , Il y a 5 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

  4. Publié par , Il y a 5 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.
    })

  5. Publié par , Il y a 5 ans

    Dur, dur l’absence d’indentation dans les commentaires …

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Nous recrutons

Être un Xebian, c'est faire partie d'un groupe de passionnés ; C'est l'opportunité de travailler et de partager avec des pairs parmi les plus talentueux.