以往因為javascript的許多殘缺設(shè)計逻淌,使得我轉(zhuǎn)身投靠iced-coffeescript(進階版coffeescript)惜纸。老實說我用的很開心跳纳,在ES5年代忍饰,當(dāng)眾多碼農(nóng)在callback hall裡苦苦掙扎之時,我已經(jīng)愉快地使用iced-coffeescript的async/await寺庄,輕鬆解決callback hell跟ES6的Promise.all
功能艾蓝。
但隨著時代的演進,javascript語言本身也進化到了ES7斗塘,源自coffeescript的胖箭頭跟async也被寫進標(biāo)準(zhǔn)了赢织,加上我受到一些啟發(fā),我想是時候重新?lián)肀S逛拱,並且好好整理一番我常用的NodeJS+Express+ES7+MySQL起手架敌厘。
首先,如果要使用async朽合,NodeJS必須升級到7.0以上俱两,過程一點都不可怕,到官網(wǎng)下載安裝檔然後下一步曹步、下一步宪彩、下一步就完成了。
此外讲婚,我還是不打算用ORM尿孔,因為只要稍微複雜一點的query,SQL還是完勝ORM
把node-mysql改成async/await
原本node-mysql的最佳實踐是用創(chuàng)造一個連線池(pool
)筹麸,把connection的生命週期交給pool
去管理/回收活合,標(biāo)準(zhǔn)用法如下
pool.query('SELECT * FROM User WHERE id=?',[1],(err,result) => {
if(err) return errorHandler(res,err);
...
});
由於async是建構(gòu)在promise之上,而node-mysql官方似乎沒有提供promise實作物赶,所以我們必須自己包:
// db.js
const db = {
query (query,params) {
return new Promise(resolve, reject) {
pool.query(query,params,(err, result) => {
if(err) reject(err);
else resolve(result);
});
}
}
}
export default db;
正由於promise會throw exception白指,使用時也必須用try catch包住
router.get('/user/:id', async (req,res) => {
try {
const user = await db.query('SELECT * FROM User WHERE id=?',[req.params.id])
const notebook = await db.query('...', otherParams)
}
catch (e) {
return errorHandler(res,err)
}
});
如果你覺得每次都要try catch太瑣碎,這裡有解決方案A酵紫、解決方案B告嘲、解決方案C错维,注意的是,當(dāng)你有多個query時橄唬,用try-catch
還是比較省心赋焕。
require進化成import
很不幸地,NodeJS 7.0還是不支援import仰楚,必須用babel轉(zhuǎn)譯隆判,而且整個app啟動時必須先require('babel-register')
,最佳實踐如下
- 修改package.json僧界,然後
npm install
"scripts": {
//假設(shè)用node-dev
"dev": "node-dev --use_strict ./bin/index"
},
"devDependencies": {
"MD5": "~1.2.0",
"babel-cli": "^6.24.1",
"babel-preset-es2015-node4": "^2.1.0",
"babel-preset-stage-3": "^6.5.0",
"babel-register": "^6.6.5",
...
}
- 新增.babelrc
{
"presets": ["es2015-node4", "stage-3"]
}
- 新增./bin/index.js
require('babel-register');
require('../app.js');
npm run dev
整理router
未完待續(xù)