##封裝思路
koa依賴co,其中間件對非阻塞異步代碼的要求必須是Yieldables列表中的形式,而mysql庫是回調函數的形式。因此,我們需要進行封裝,使其接口符合要求。
目前我找到了四種方法,前三種使用開源庫,第四種自己動手,將express下的dbHelper層封裝成co最新支持的Promise形式。
##實現方法一(co-mysql)
co-mysql和mysql-co實現了對mysql或mysql2的封裝轉化。這兩個庫的思路差不多,mysql-co封裝度更高,并使用速度更快的mysql2;而co-mysql更簡單,只是將mysql.query封裝成Promise形式。下面是基于co-mysql的示例代碼:
```
var wrapper = require('co-mysql'),
mysql = require('mysql');
var options = { /* 數據庫連接字串 */ };
var pool = mysql.createPool(options),
p = wrapper(pool);
...
var rows = yield p.query('SELECT 1');
yield this.render('index', {
title: rows[0].fieldName
});
...
})();
```
##實現方法二(promisify-node)
使用promisify-node庫,可以將庫整體轉化為Promise形式,也可以方便的轉化庫中的指定接口函數,示例代碼如下:
```
var promisify = require("promisify-node");
var db = promisify("dbHelper"); //express下的回調形式封裝庫
...
var rows = yield db.getById('tableName', {id:1});
yield this.render('index', {
title: rows[0].fieldName
});
...
```
##實現方法三(thunkify)
使用thunkify也能夠完成封裝,thunkify-wrap是一個增強版的thunkify。不過看說明,這種方法在未來的發展中可能會被淘汰,大概的使用方法如下:
```
var genify = require('thunkify-wrap').genify;
var db = genify("dbHelper"); //express下的回調形式封裝庫
...
var rows = yield db.getById('tableName', {id:1});
yield this.render('index', {
title: rows[0].fieldName
});
...
```
##實現方法四(直接方法)
直接改造原來express下的回調方式代碼為Promise形式,代碼及說明如下:
dbHelper.js
```
var options = { /* 數據庫連接字串 */ };
var mysql = require('mysql');
var pool = mysql.createPool(options);
//原有非接口代碼,對mysql的封裝,執行sql語句
function execQuery(sql, values, callback) {
var errinfo;
pool.getConnection(function(err, connection) {
if (err) {
errinfo = 'DB-獲取數據庫連接異常!';
throw errinfo;
} else {
var querys = connection.query(sql, values, function(err, rows) {
release(connection);
if (err) {
errinfo = 'DB-SQL語句執行錯誤:' + err;
callback(err);
} else {
callback(null,rows); //注意:第一個參數必須為null
}
});
}
});
}
function release(connection) {
try {
connection.release(function(error) {
if (error) {
console.log('DB-關閉數據庫連接異常!');
}
});
} catch (err) {}
}
//對外接口代碼,包裝成返回Promise函數的形式
exports.getById = function(tablename, id){
return new Promise(function(resolve, reject){
var values = {id:id};
var sql = 'select * from ?? where ?';
execQuery(sql,[tablename, values], function(err, rows){
if(err){
reject(err);
}else{
resolve(rows);
}
})
});
}
```
routes/index.js
```
var db = require("../dbHelper");
...
var rows = yield db.getById('tableName', {id:1});
yield this.render('index', {
title: rows[0].fieldName
});
...
```
##代碼
示例部分代碼取自該項目:
```
https://github.com/zhoutk/koadmin.git
```
##小結
koa框架以co庫為核心組織,很好的用generator來解決了回調函數問題。進行Promise接口形式包裝的時候,要注意:回調函數要完全符合其要求的形式:
```
function(err, rows){
if(err){
reject(err);
}else{
resolve(rows);
}
})
```
- Introduction
- Nodejs 4.x新特性
- classes
- typed arrays
- generators
- collections
- Set
- Map
- arrow functions
- block scoping
- template strings
- promises
- symbols
- Koa基礎
- 上下文
- koa-generator
- 安裝
- 創建項目
- 更改視圖模板引擎
- Routes
- HTTP
- Get
- 如何獲取query參數
- 如何獲取params
- Post
- 從post獲取參數
- 標準表單(Post with x-www-form-urlencoded)
- 文件上傳(Post with form-data)
- Post with raw
- 數據庫
- MySQL
- Mongo
- 流程控制
- generator/co
- es6的generator是什么?
- co = generator + promise
- async/await
- promise with bluebird
- 測試
- Mocha
- Supertest
- 部署
- 最佳實踐
- FAQ
- 如何發布本書到git pages
- 如何知道require模塊的用法
- koa中的異常處理