在节点js中使用Promises

时间:2015-10-26 12:36:51

标签: node.js promise ejs bluebird

我是nodejs的新手。我已经开始学习nodejs了。我想在nodejs中使用promises。我已经成功安装了bluebird.Cureently我的代码看起来:

req.getConnection(function(err,connection){
  var query = connection.query('SELECT node_questions.question_name,node_questions.description FROM node_questions LEFT JOIN node_user ON node_questions.user_id=node_user.id;SELECT * FROM node_user ORDER BY points DESC LIMIT 5',function(err,rows)
        {

     var data =rows[0];
     var data2 = rows[1];
      console.log(data);
      console.log(data2);
             res.render('index', { page_title: 'Welcome',session:req.session.userId,email:req.session.email,data:data,data2:data2});
         });

    });
};

我想在这里使用承诺。我该怎么办。

请帮忙......

2 个答案:

答案 0 :(得分:2)

var promise = require('bluebird');

var getRows = function () {

   var deferred = promise.pending();

   var query = connection.query('SELECT node_questions.question_name,node_questions.description FROM node_questions LEFT JOIN node_user ON node_questions.user_id=node_user.id;SELECT * FROM node_user ORDER BY points DESC LIMIT 5',function(err,rows) {
        if(!err) deferred.fulfill(rows);
        else deferred.reject(err.message);
   });

   return deferred.promise;
}

你可以调用下面的函数;

getRows()
.then(function(rows) {
// make somethings with rows data here
})
.catch(function(err) {
   // you can get rejected data here
})

答案 1 :(得分:2)

使用Bluebird,您可以使用它的.promisify()方法制作遵循nodejs调用约定的任何异步函数的promisified版本。在这种情况下,您可以这样做:

var Promise = require('bluebird');
var getConnection = Promise.promisify(req.getConnection, req);

getConnection().then(function(connection) {
    var query = Promise.promisify(connection.query, connection);
    return query('SELECT node_questions.question_name,node_questions.description FROM node_questions LEFT JOIN node_user ON node_questions.user_id=node_user.id;SELECT * FROM node_user ORDER BY points DESC LIMIT 5');
}).spread(function(rows, fields) {
     // process result here
     console.log("rows = ", rows);
     var data = rows[0];
     var data2 = rows[1];
     console.log(data);
     console.log(data2);
     res.render('index', {
         page_title: 'Welcome',
         session: req.session.userId,
         email: req.session.email,
         data: data,
         data2: data2
     });
}, function(err) {
     // process error here
});

通常当你想要转换某些东西以使用承诺时,你可以" promisify"你的函数只需要在一个模块中运行一次,然后在模块的其余部分使用该promisified版本,就像上面显示的getConnection()函数一样。 connection.query()情况有点独特,因为connection对象是动态创建的对象,因此每次创建新的连接对象时都必须对其进行委托。

虽然通常更好地宣传异步操作的每个阶段(正如我上面所做的那样),因为它可以实现更清晰,更一致的错误处理和错误传播,你也可以只包装所有传统的回调内容像这样的一个承诺(虽然强大的实现也需要在内部捕获异常并将它们变成被拒绝的承诺,但你可以在这里看到一般的想法):

new Promise(function (resolve, reject) {
    req.getConnection(function (err, connection) {
        if (err) return reject(err);
        var query = connection.query('SELECT node_questions.question_name,node_questions.description FROM node_questions LEFT JOIN node_user ON node_questions.user_id=node_user.id;SELECT * FROM node_user ORDER BY points DESC LIMIT 5', function (err, rows, fields) {
            if (err) 
                reject(err);
            else
                resolve(rows);
        });
    });
}).then(function(rows) {
     // process result here
     var data = rows[0];
     var data2 = rows[1];
     console.log(data);
     console.log(data2);
     res.render('index', {
         page_title: 'Welcome',
         session: req.session.userId,
         email: req.session.email,
         data: data,
         data2: data2
     });
}, function(err) {
     // process error here
});