1. 程式人生 > >在Node.js使用Promise的方式操作Mysql

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

lds 回調 mysql連接 contact 只需要 rom undefine easyn resolve

最近在學習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