在node.js中使用mysql和promises

x33g5p2x  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(532)

我只是按照scotch.io中关于节点身份验证的教程进行了操作。他们使用mongodb作为后端,我将其移植到mysql。这是我第一个连接到数据库的节点应用程序。
我用蓝知更鸟 promisify 这个 mysqljs/mysql Package config/database.js ```
const mysql = require('mysql');
const Promise = require("bluebird");
Promise.promisifyAll(mysql);
Promise.promisifyAll(require("mysql/lib/Connection").prototype);
Promise.promisifyAll(require("mysql/lib/Pool").prototype);

这是我的密码 `model/user.js` : 

const mysqlPool = require('../../config/database'),
bcrypt = require('bcrypt-nodejs'),
Promise = require("bluebird");
getDb = function(){
return mysqlPool.getConnectionAsync();
}
let user = {
create(user, done) {
getDb().then((db) => {
return db.queryAsync(insert into bot_users (name, token, type, external_id) values (?, ?, ?, ?),
[user.name, user.token, user.type, user.external_id])
}).then((results, fields) => {
console.log(results, fields)
user.id = results.insertId
return done(null, user)
})
},

我觉得有些东西不太好:

getDb().then((db) => {
return db.queryAsync(...)
}).then(...)

看起来有点复杂。我想要一个变量 `db` 我可以直接用作 `db.queryAsync(...).then(...)` ,但我无法找到如何将这样的承诺赋给变量 `db` .
此外,我想对我的做法提出建议。这是使用承诺的好方法还是有更好的方法?
有必要吗 `return done(null, user)` 内部 `then` 回调以遵守常规节点约定,还是在使用promises(bluebird)时不再需要回调?
3duebb1j

3duebb1j1#

你可以简单地回报 create 方法 user 模型。

create(user) {
    return getDb().then((db) => {
        return db.queryAsync(`insert into bot_users (name, token, type, external_id) values (?, ?, ?, ?)`,
            [user.name, user.token, user.type, user.external_id])
    }).then((results, fields) => {
        console.log(results, fields)
        user.id = results.insertId
        return user;
    })
},

这个承诺将与用户的价值相一致。所以在其他任何地方你都可以使用这个方法

User.create(user)
.then(createdUser => { // do something with user here })

如果您可以访问node的最新版本(8以上的任何版本),则可以使用 async-await ,使代码更易于理解。

async create(user) {
    const db = await getDb();
    const results = await db.queryAsync(`insert into bot_users (name, token, type, external_id) values (?, ?, ?, ?)`,
            [user.name, user.token, user.type, user.external_id]);
    user.id = results.insertId;
    return user;
},

async 函数可以像任何其他函数一样调用,但它将返回一个承诺,该承诺将与返回的值进行解析。所以这个方法的用法还是一样的。

User.create(user)
.then(createdUser => { // do something with user here })
yiytaume

yiytaume2#

对于任何有承诺的工作,最重要的建议是:放弃回调。
您的代码当前是回调之间的混合( done() )还有承诺。别那么做。只使用承诺。承诺的关键点是可以从异步函数返回一些东西。您不需要依赖调用方传入回调。
承诺所有API。强调归还物品。

const Promise = require("bluebird"),
    mysqlPool = Promise.promisifyAll(require('../../config/database')),
    bcrypt = Promise.promisifyAll(require('bcrypt-nodejs'));

let user = {
    create: params => mysqlPool
        .getConnectionAsync()
        .then(db => db.queryAsync(
            'insert into bot_users (name, token, type, external_id) values (?, ?, ?, ?)',
            [params.name, params.token, params.type, params.external_id]
        ))
        .then((results, fields) => ({
            name: params.name,
            token: params.token,
            type: params.type,
            external_id: params.external_id,
            id: results.insertId
        }))
};

注意如何 user.create() 返回一个完整的值链。mysql连接变成查询结果变成新的用户对象。我不喜欢重写现有示例。避免副作用。
用法很简单。

user.create({
    name: "foo",
    token: 12345,
    type: "user",
    external_id: 67890
}).then(newUser => {
    console.log(newUser);
}).catch(err => {
    console.error(err);
});

相关问题