5、Express異步讀取Mysql數(shù)據(jù)庫(kù) callback/promise/async

一、Node異步

Node.js 異步編程的直接體現(xiàn)就是回調(diào)。

有了異步方法,我們可以一邊操作數(shù)據(jù)庫(kù),一邊執(zhí)行其他命令,在數(shù)據(jù)庫(kù)操作完成后,我們將查詢數(shù)據(jù)作為回調(diào)函數(shù)的參數(shù)返回。這樣在執(zhí)行代碼時(shí)就沒有阻塞或等待 I/O的 操作。這就大大提高了 服務(wù)器運(yùn)行 的性能,可以更容易的處理大量的并發(fā)請(qǐng)求。

二、Mysql數(shù)據(jù)庫(kù)連接

1.package.json下添加mysql依賴,cmd命令行中找到項(xiàng)目目錄執(zhí)行 npm install(或者webstorm中 package.json 右鍵 >> Run 'npm update')


建立目錄:

conf >> localmysql.js:

module.exports = {

mysql: {

host: 'localhost',

user: 'root',

password: '3721',

database:'weixin',

port: 3306

}

};

model>> usermodel.js:

const?user = {

queryUserByCity:'SELECT nickname FROM userinfo WHERE city = ? ',

};

module.exports = user;


dao >>userDao.js :

const mysql = require('mysql');

const conf = require('../conf/localmysql');

const sql = require('../model/usermodel');

//使用連接池

const pool = mysql.createPool(conf.mysql);

module.exports = {

queryCallBackByCity:(city,callback)=>{

pool.getConnection((err,con)=>{

con.query(sql.queryUserByCity,city,(err,result)=>{

if(err){

callback(err);

}

else {

callback(err,result);

}

})

})

}

};

這里建議確定下來不需要?jiǎng)討B(tài)變更的變量使用const定義 (阮一峰-const 命令

三、CallBack 回調(diào)寫法

在router里定義路由

router.get('/queryuser', (req, res, next)=> {

let data = [];

userDao.queryCallBackByCity('Xuzhou',(err,result)=>{

data.push(result);

});

data.push('哈哈哈');

res.json(data);

});

執(zhí)行以后發(fā)現(xiàn)頁(yè)面只輸出‘哈哈哈’(res.json 輸出json格式數(shù)據(jù));

改為:

router.get('/queryuser', (req, res, next)=> {

let data = [];

userDao.queryCallBackByCity('Xuzhou',(err,result)=>{

data.push(result);

data.push('哈哈哈');

res.json(data);

});

});

則按著想要的順序輸出了輸出正常

因?yàn)楫惒阶x取,Node會(huì)將任務(wù)交給地下的線程池操作,線程池操作完成后會(huì)發(fā)起回調(diào)函數(shù)觸發(fā),所以順序執(zhí)行的方法是一層前一層 callback hell(地獄回調(diào));

如果多次讀取就會(huì)寫成:


可以想象復(fù)雜的業(yè)務(wù)邏輯

隨意后來有了解決方案2 Promise:

四、Prmoise寫法

首先定義userModel:


可以看出來 callback變成 return new Promise 執(zhí)行成功執(zhí)行 resovle 執(zhí)行失敗 reject

router調(diào)用,在調(diào)用函數(shù)后面加 調(diào)用成功then,調(diào)用失敗catch:

router.get('/queryuser3', (req, res, next)=> {

let data = [];

userDao.queryPromiseByCity('Changzhou').then((r)=>{

data.push(r);

res.json(data);

}).catch(err=>{

return console.log(err);

})

});

這樣,就可以寫出鏈?zhǔn)交卣{(diào)寫法,雖然依舊惡心,但至少美觀了不少,并且錯(cuò)誤處理只需要一個(gè)catch就可以


五、終極解決方案:Async

async需要node 7.X版本支持

如小于7.X版本可以選擇使用Bable或者升級(jí),windows下升級(jí)可以看我的這篇博客

使用 async/await 調(diào)用Promise對(duì)象可以直接當(dāng)作同步來寫,但是目前7.X未出穩(wěn)定版,es2017還未正式發(fā)布,謹(jǐn)慎使用。


如圖,兩種方法,async可以在路由里定義async函數(shù) (需要加括號(hào)表名作用域)下

或者定義在執(zhí)行函數(shù)里,上

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容