由 Express 原班人马打造的 koa,致力于成为一个更小、更健壮、更富有表现力的 Web 框架。使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函数嵌套,并极大地提升常用错误处理效率。Koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。
安装koa
koa 依赖支持 generator 的 Node 环境,也就是说,node的版本要在 0.11.9 或者更高,否则将无法执行。
用npm:
$ npm install koa
或者,选择安装在全局:
$ npm install -g koa
Example
这是一个koa的简单例子:
var koa = require('koa'); var app = koa(); // logger app.use(function *(next){ var start = new Date; yield next; var ms = new Date - start; console.log('%s %s - %s', this.method, this.url, ms); }); // response app.use(function *(){ this.body = 'Hello World'; }); app.listen(3000);
与普通的 function 不同,generator functions 以 function* 声明。以这种关键词声明的函数支持 yield。在后面会讲到 yield 的用法和意义。
执行koa
执行koa时需要在 —-harmony 模式下运行,为了方便可以将 node 设置为默认启动 harmony 模式的别名:
alias node='node --harmony'
这样在执行相关js的时候就可以直接使用了。
Cascading
这是一个比较抽象的概念。Koa 中间件以一种非常传统的方式级联起来,也就是这里所谓的Cascading。
在以往的 Node 开发中,频繁使用回调不太便于展示复杂的代码逻辑,在 Koa 中,我们可以写出真正具有表现力的中间件。与 Connect 实现中间件的方法相对比,Koa 的做法不是简单的将控制权依次移交给一个又一个的中间件直到程序结束,Koa 执行代码的方式有点像回形针,用户请求通过中间件,遇到 yield next 关键字时,会被传递到下一个符合请求的路由(downstream),在 yield next 捕获不到下一个中间件时,逆序返回继续执行代码(upstream)。
下边这个例子展现了使用这一特殊方法书写的 Hello World 范例:一开始,用户的请求通过 x-response-time 中间件和 logging 中间件,这两个中间件记录了一些请求细节,然后「穿过」 response 中间件一次,最终结束请求,返回 「Hello World」。
当程序运行到 yield next 时,代码流会暂停执行这个中间件的剩余代码,转而切换到下一个被定义的中间件执行代码,这样切换控制权的方式,被称为 downstream,当没有下一个中间件执行 downstream 的时候,代码将会逆序执行。
var koa = require('koa'); var app = koa(); // x-response-time app.use(function *(next){ // (1) 进入路由 var start = new Date; yield next; // (5) 再次进入 x-response-time 中间件,记录2次通过此中间件「穿越」的时间 var ms = new Date - start; this.set('X-Response-Time', ms + 'ms'); // (6) 返回 this.body }); // logger app.use(function *(next){ // (2) 进入 logger 中间件 var start = new Date; yield next; // (4) 再次进入 logger 中间件,记录2次通过此中间件「穿越」的时间 var ms = new Date - start; console.log('%s %s - %s', this.method, this.url, ms); }); // response app.use(function *(){ // (3) 进入 response 中间件,没有捕获到下一个符合条件的中间件,传递到 upstream this.body = 'Hello World'; }); app.listen(3000);
在上方的范例代码中,中间件以此被执行的顺序已经在注释中标记出来。你也可以自己尝试运行一下这个范例,并打印记录下各个环节的输出与耗时。
.middleware1 { // (1) do some stuff .middleware2 { // (2) do some other stuff .middleware3 { // (3) NO next yield ! // this.body = 'hello world' } // (4) do some other stuff later } // (5) do some stuff lastest and return }
上方的伪代码中标注了中间件的执行顺序,看起来是不是有点像 ruby 执行代码块(block)时 yield 的表现了?也许这能帮助你更好的理解 koa 运作的方式。
koa访问mysql数据库操作
实现方法一(co-mysql)
mysql库是以回调形式实现的,而koa中间件要求Promise形式,经过搜索,发现了co-mysql和mysql-co,这两个库的思路差不多,mysql-co封装度更高,并使用速度更快的mysql2,而co-mysql更简单,只是将mysql.query封装成Promise形式。下面是基于co-mysql的写法
var wrapper = require('co-mysql'), mysql = require('mysql'); var options = { host : 'localhost', port : 3306 , database : 'test', user: 'root', password : 'rootroot' }; 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("myDbHelper"); ... var rows = yield db.getById('tableName', {id:1}); yield this.render('index', { title: rows[0].fieldName }); ...
实现方法三(thunkify、thunkify-wrap)
使用thunkify也能够完成封装,thunkify-wrap是一个增强版的thunkify,不过看说明,这种方法在未来的发展中可能会被淘汰,大概的使用如下:
var genify = require('thunkify-wrap').genify; var db = genify("myDbHelper"); ... var rows = yield db.getById('tableName', {id:1}); yield this.render('index', { title: rows[0].fieldName }); ...
实现方法四(直接方法)
直接改造原来express下的代码为Promise形式,参考了co-mysql,并仔细学习了Promise相关知识,完成了已有代码的改造,代码及说明如下:
dbHelper.js
var config = require('./dbconfig'); var options = { 'host': config.db_host, 'port': config.db_port, 'database': config.db_name, 'user': config.db_user, 'password': config.db_passwd } 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
本文向大家介绍Node.js的Express框架使用上手指南,包括了Node.js的Express框架使用上手指南的使用技巧和注意事项,需要的朋友参考一下 Express介绍 npm提供了大量的第三方模块,其中不乏许多Web框架,比如我们本章节要讲述的一个轻量级的Web框架 ——— Express。 Express是一个简洁、灵活的node.js Web应用开发框架, 它提供一系列强大的功能,比如
本文向大家介绍Laravel框架Request、Response及Session操作示例,包括了Laravel框架Request、Response及Session操作示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Laravel框架Request、Response及Session操作。分享给大家供大家参考,具体如下: Request操作 Response操作 Session操作 更多关
本文向大家介绍如何从头实现一个node.js的koa框架,包括了如何从头实现一个node.js的koa框架的使用技巧和注意事项,需要的朋友参考一下 前言 koa.js是最流行的node.js后端框架之一,有很多网站都使用koa进行开发,同时社区也涌现出了一大批基于koa封装的企业级框架。然而,在这些亮眼的成绩背后,作为核心引擎的koa代码库本身,却非常的精简,不得不让人惊叹于其巧妙的设计。 在平时
本文向大家介绍JavaScript的模块化开发框架Sea.js上手指南,包括了JavaScript的模块化开发框架Sea.js上手指南的使用技巧和注意事项,需要的朋友参考一下 Sea.js所有源码都存放在 GitHub 上:https://github.com/seajs/examples,目录结构为: 引入seajs主文件 seajs主入口文件(main) seajs依赖文件(index) 文件
本文向大家介绍node.js 开发指南 – Node.js 连接 MySQL 并进行数据库操作,包括了node.js 开发指南 – Node.js 连接 MySQL 并进行数据库操作的使用技巧和注意事项,需要的朋友参考一下 Node.js是一套用来编写高性能网络服务器的JavaScript工具包 通常在NodeJS开发中我们经常涉及到操作数据库,尤其是 MySQL ,作为应用最为广泛的开源数据
本文向大家介绍Node.js与MySQL交互操作及其注意事项,包括了Node.js与MySQL交互操作及其注意事项的使用技巧和注意事项,需要的朋友参考一下 node.js作为服务端的js运行环境已经出现了有几年了,最近我有个朋友也在做这方面的开发,但是也是刚刚接触,遇到了很多坑。前几天他们在操作数据库的时候出现了点问题,后来我们一起看了看,其实都是node本身机制的一些问题,这里总结一下给新手做借