简体   繁体   中英

Using Q promise library with Express.js and Mongoose

I've never used promises and am exploring them using an express.js/mongo app I wrote. Below are one of the routes that query mongo and then set the result as a property on an object in the render method arguments ( to be used by the template engine). I am curious how to write this in a "promise" style using Q . I've been fiddling for about an hour and decided to throw in the towel and ask.

app.get("/", function(req, res) {
    Comment.find(function(err, item) {

        res.render("index", {
            comment: item

        })
    })
})

if you are not persistant that it has to be done on q , you can use bluebird and promisify:

var Promise = require("bluebird");
Promise.promisifyAll(Comment);

app.get("/", function(req, res) {
    Comment.find()  // now this is already a promisified method
        .then(function(item){
            res.render("index", { comment: item });
        }).catch(function(err){
            res.render('error', { error: err });
        });
});

I don't think q has such promisification method, so, in q, using deferred :

var Q = require("q");
app.get("/", function(req, res) {

    var deferred = Q.defer();
    Comment.find(function(err, item) {
        if(err)    return deferred.reject(error);
        deferred.resolve(item);
    });

    deferred.promise
        .then(function(item){
            res.render("index", { comment: item });
        }).catch(function(err){
            res.render('error', { error: err });
        });
});

You'd use Q.ninvoke to get a promise for the item :

var itemPromise = Q.ninvoke(Comment, "find");

Now you can chain a .then to that - basically attaching two callbacks:

itemPromise.then(function(item) {
    // success case
    res.render("index", {
        comment: item
    });
}, function(err) {
    // error case
    res.render("index", {
        comment: undefined // reflecting your original code, but hardly what you want
    });
});

In this case, promises don't have lots of advantage. You cannot use them for app.get btw, as that might be an asynchronous callback, but for multiple events not for a single result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM