多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
##封装思路 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); } }) ```