如何使用promises转换此代码?

时间:2015-06-17 09:39:18

标签: node.js callback promise

我是Nodejs.的新手。我想将此代码转换为promises(nodejs)。这包括四个回调函数get(),abc1(),pqr(),xyz()。它给出了“无法读取属性”然后“未定义”的错误“任何人都可以修复它吗?我正在尝试将此转换为此示例中的承诺here

var jwt = require('jwt-simple');
var mysql = require('mysql');
var async = require('async');
var Promise = require('bluebird');

var connection = mysql.createConnection({
    host: 'localhost',
    port: 3306,
    database: 'abc',
    user: 'root',
    password: ''
});


var auth = {
    login: function (req, res) {
        var username = req.body.username || '';
        var password = req.body.password || '';
        console.log(req.body);
        //This is get() function 
        function get(err, rows) {
            connection.connect(function (err) {
                if (err) {
                    console.error('error connecting: ' + err.stack);
                    return;
                } else {
                    console.log("connected to database");
                    connection.query("SELECT count(id) as count from abc where name=? AND email=?", [username, password], function (err, rows) {
                        if (err) {
                            throw err
                        } else {

                            b = rows;
                            console.log(b);
                        }
                    });
                }
            });
        }

        //this is abc1() function                
        function abc1(err, rows) {
            console.log("onresult");
            if (err) {
                throw err;
                console.log("error in Query");
            } else {
                if (rows[0].count != 1) {
                    //xyz(result,xyz);
                    res.json({
                        "status": 401,
                        "message": "Invalid credentials"
                    });
                } else {
                    connection.query("SELECT email from abc where name=? AND email=?", [username, password], function (err, rows) {});
                    //res.json(genToken("ayush"));
                }
            }
        }
        //This is xyz() function
        function xyz(err, rows) {
            if (err) {
                console.log(err);
            }
            console.log(rows);
            connection.query("SELECT name from abc where name=? AND email=?", [username, password], function (err, rows) {});
        }
        //This is pqr() Function    
        function pqr(err, rows) {
            if (err) {
                console.log(err);
            }
            console.log(rows);
        }
        get()
            .then(function (rows) {
                // do something...
                //console.log("hellow1");
                return abc1();
            })
            .then(function (rows) {
                // do something...  
                console.log("hellow2");
                return xyz();
            })
            .then(function (rows) {
                // the third and final async response
                console.log("hellow3");
                return pqr();
            })
            .then(function (rows) {
                // the third and final async response
                console.log("hellow4");
            })
            .fail(function (err) {
                // handle any error resulting from any of the above calls 
                throw err;
            })
            .done();
    }
}

1 个答案:

答案 0 :(得分:0)

使用参数(err, rows),所有四个函数似乎都被编写为nodebacks,我们可以精确地猜测原始工作代码的样子。

如果不进行修改,nodebacks只能用作nodebacks。将它们原始插入到承诺链中是行不通的。

但是你的功能将在以下方面的诺言链中起作用:

  • 宣传基础的asycn函数,即connection的方法。
  • 在函数中调用connection.methodAsync()版本的方法而不是connection.method()
  • 从您的每个职能中回复承诺。

通过一点{/ 1}}函数而不是connect()开始重新命名/重构,整个过程实际上效果更好。

get()

正如您将看到的那样,var jwt = require('jwt-simple'); var mysql = require('mysql'); var async = require('async'); var Promise = require('bluebird'); var connection = mysql.createConnection({ host: 'localhost', port: 3306, database: 'abc', user: 'root', password: '' }); //Promisify `connection`. //Lucky you, Bluebird has a `.promisifyAll()` method. Promise.promisifyAll(connection); //Now, `auth` will be something like this : var auth = { login: function (req, res) { var username = req.body.username || ''; var password = req.body.password || ''; //Let's assume you want to build an object containing various user details var authObj = { 'userName': userName, 'email': null, //to be set later 'name': null //to be set later }; function connect() { return connection.connectAsync().catch(function(err) { throw 'Error connecting: ' + err.stack; }); } function abc1() { return connection.queryAsync("SELECT count(id) as count from abc where name=? AND email=?", [username, password]).then(function (rows) { if (rows[0].count != 1) { throw new Error('Invalid credentials'); } }); } function xyz() { return connection.queryAsync("SELECT email from abc where name=? AND email=?", [username, password]).then(function(rows) { return rows[0].email; }); } function pqr() { return connection.queryAsync("SELECT name from abc where name=? AND email=?", [username, password]).then(function(rows) { return rows[0].name; }); } return connect() .then(abc1)//check credentials .then(xyz)//get email .then(function (email) { authObj.email = email; return pqr();//get name }) .then(function (name) { authObj.name = name; return authObj;//make authObj available to auth.login()'s caller. }) .catch(function (err) { // handle any error resulting from any of the above calls. console.log(err); throw err;//make the error available to auth.login()'s caller. }); } } err的底部直到代码中才会显示。突发的nodebacks的本质是错误沿着promise链的错误路径传播,除非你需要做中链错误恢复之类的事情,否则不需要在链中处理。

虽然这有助于学习如何构建一个承诺链,但实际上你在一开始就已经知道了名字和电子邮件了,你可能会选择登录并在一个匹配中使用合适的SQL获取其他用户详细信息。< / p>