如何使用 promises 转换此代码?

How do I convert this code using promises?

我是新手 Nodejs.I 想把这段代码转换成 promises (nodejs)。这包括四个回调函数 get(),abc1(),pqr(),xyz()。它给出 "cannot read property 'then' of undefined" 的错误 谁能修复它?我正在尝试将其转换为此示例中的承诺 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();
    }
}

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

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

但是您的函数将在 :

之后在承诺链中运行
  • 承诺底层异步函数,即connection的方法。
  • 在函数中调用 connection.methodAsync() 版本的方法而不是 connection.method()
  • 从您的每个函数返回一个承诺。

整个事情实际上用一点点 renaming/refactoring 从 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 直到 auth.login() 的底部才出现在代码中。 promised nodebacks 的本质是错误会沿着 promise 链的错误路径传播,并且不需要在链中处理,除非你需要做一些类似链中错误恢复的事情。

虽然这对于学习如何构建承诺链很有帮助,但实际上您一开始似乎已经知道姓名和电子邮件,并且您可能会选择登录并一次性获得其他用户详细信息 SQL.