在Node.js使用Promise的方式操作Mysql

Posted 湛蓝玫瑰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Node.js使用Promise的方式操作Mysql相关的知识,希望对你有一定的参考价值。

最近在学习Node.js,虽然早就听说了回调地狱结果过了一周就遇到了。所以花时间学习了了一下Promise。虽然还有Async/await、co、生成器等选择,但是因为本人基础较差,以及时间问题所以决定先用好Promise。

 

你可以选择用原生的,当然最好还是用BlueBird,听说性能比官方的好很多,而且有额外的特性:promisifyAll、Promisify

官方案例:

var fs = Promise.promisifyAll(require("fs"));

fs.readFileAsync("myfile.js", "utf8").then(function(contents) {
    console.log(contents);
}).catch(function(e) {
    console.error(e.stack);
});

  

 

首先如果要使用.then语句只能在Promise对象后面使用,于是乎你必须修改原始的连接代码,让他返回一个Promise对象。当然

 

使用的原始mysql连接代码:

var mysql=require("mysql")
var settings=require(‘../settings‘);
var pool = mysql.createPool({
    host: settings.host,
    user: settings.user,
    password: settings.password,
    database: settings.db,
    port:settings.port
});

module.exports=function(sql,callback){
    pool.getConnection(function(err,conn){
        if(err){
            callback(err,null,null);
        }else{
            conn.query(sql,function(err,rows,fields){
                //释放连接
                conn.release();
                //事件驱动回调
                callback(err,rows,fields);
            });
        }
    });
};

  将下面这段代码改成:

module.exports=function (sql) {
    return new Promise(function (resolve, reject) {
        pool.getConnection(function(err,conn){
            if(err){
                reject(err);
            }else{
                conn.query(sql,function(err,rows,fields){
                    //释放连接
                    conn.release();
                    //传递Promise回调对象
                    resolve({"err":err,
                            "rows":rows,
                            "fields":fields});
                });
            }
        });
    });
};

  这里解释一下一下reject与resolve这2个关键字:

reject:抛出一个异常,在最近的.catch()中接收并且处理他。

resolve:传递数据至下一个.then语句中。

这里我用resolve({"err":err,"rows":rows,"fields":fields}); 因为resolve不能传递多个对象,所以可以考虑数组或者组合成一个对象的。

 

使用案例:

var express = require(‘express‘);
var query=require(‘../module/mysql‘);
var JSON=require(‘JSON‘);
var router = express.Router();


router.post(‘/uploads/uploadFactoryInfo‘,function (req, res, next) {
    var factoryName=req.body.factoryName;
    var factoryAdress=req.body.factoryAdress;
    var contactInfo=req.body.contactInfo;
    var remark=req.body.remark;
    var updateDate=req.body.updateDate;
    var handleUserName=req.session.loginUser;
    //判断厂家名是否重复,如果重复则返回错误信息
    query("select * from  managersystem.factoryinfo where factoryName=‘" +factoryName +"‘;").
    then(function (data) {
        if(data.rows[0]!=undefined)
        {
            res.json({message:‘该厂家信息已经录入!‘});
            return;
        }
    }).then(function () {
        query("INSERT INTO managersystem.factoryinfo (factoryName, infoUpdateTime, contactInfo, address, remark) " +
            "VALUES (‘"+factoryName+"‘, ‘"+updateDate+"‘, ‘"+contactInfo+"‘, ‘"+factoryAdress+"‘, ‘"+remark+"‘);");
    }).then(function () {
        query("select * from  managersystem.factoryinfo where factoryName=‘" +factoryName +"‘;").
        then(function (data) {
            var sql = "INSERT INTO managersystem.useractionrecords (`handleUserName`, ` handleTableName`, ` handleTableId`, `oldData`, `newData`, `action`, `dateTime`)  " +
                "VALUES (‘" + handleUserName + "‘, ‘factoryinfo‘, ‘" + data.rows[0].id + "‘, null, ‘" + factoryName + "‘, ‘插入新数据‘, now());";
            query(sql);
            res.json({message:‘插入数据成功!‘});
        })
    }).catch(function (err) {console.log(err);});
});

  

 

使用Promise的感觉:

1、不用在每个回调函数中处理错误了,只需要在最后一个处理一下就好了,当然你可以在你想要处理的地方处理。

2、避免回调地狱,层层嵌套看得自己都恶心起来了。

以上是关于在Node.js使用Promise的方式操作Mysql的主要内容,如果未能解决你的问题,请参考以下文章

Node.js——NodeJs中的Promise

Node.js 探秘 - 求异存同

利用async和await异步操作解决node.js里面fs模块异步读写,同步结果的问题

Node.js匿名函数-闭包-Promise

使用 Q 在 Node.js 中同步 Promise 的麻烦

Promise--实践练习之fs模块 & node运行Js脚本 & Promise封装练习-fs模块 & util.promisify方法