koa是Express的下一代基于Node.js的web框架,目前有1.x和2.0两个版本。
koa 1.0 用es6的generator来实现异步
doreadFile()等有值时就返回。
var koa = require('koa');
var app = koa();
app.use('/test', function *() {
yield doReadFile1();
var data = yield doReadFile2();
this.body = data;
});
app.listen(3000);
为了简化异步代码,es7引入了关键字async和await,可以轻松把一个function变为一个异步模式。例如如下:
app.use(async (ctx, next) => {
await next();
var data = await doReadFile();
ctx.response.type = 'text/plain';
ctx.response.body = data;
});
创建koa项目 使用npm init创建node 项目,其中有package.json文件,是整个项目的配置文件,如下内容。
、
//post 请求中用来解析参数bodyparser
const bodyparser = require('koa-bodyparser');
//使用
app.use(bodyParser());
{
"name": "hello-koa2",
"version": "1.0.0",
"description": "Hello Koa 2 example with async",
"main": "app.js",
"scripts": {
"start": "node app.js"
},
"keywords": [
"koa",
"async"
],
"author": "Michael Liao",
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "https://github.com/michaelliao/learn-javascript.git"
},
"dependencies": {
"koa": "2.0.0",
"koa-router": "7.0.0",
"koa-bodyparser": "3.2.0"
}
}
表示一些描述文件,scripts 表示入口文件 本文中是app.js文件。dependence表示引用的包。
导入koa
//导入koa 导入的是一个class 因此用大写的Koa表示
const Koa = require('koa');
//创建一个Koa对象表示web app本身
const app = new Koa();
对于每一个http请求,koa将调用我们传入的异步函数来处理。
app.use(async(ctx,next) =>{
console.log("process");
await next();
});
参数ctx表示上下文,封装了request和response变量,,我们可以通过它访问request和response,
next
是koa传入的将要处理的下一个异步函数。上面函数中 使用await next()表示处理下一个异步函数,只有等这个处理完了,才能执行下面的代码。
app.listen表示监听的端口。
await next()的作用。 koa把async函数组成一个处理链,买个async函数都可以做一些自己的函数,然后用await next()来调用下一个async函数,我们把每个async函数称为middleware 中间件,这些middleware可以组合起来,完成很多有用的功能。
我们可以写如下函数来查看middleware的调用顺序。
app.use(async(ctx,next)=>{
console.log("1"); //等这里执行好 调用下一个异步函数
await next();
console.log(`${ctx.request.method} ${ctx.request.url}`); // 打印URL
});
app.use(async(ctx,next) => {
const start = new Date().getTime(); // 当前时间
console.log(2);
await next();
const ms = new Date().getTime() - start; //等异步函数执行好 再执行这里 耗费时间
console.log(`Time: ${ms}ms`); // 打印耗费时间
});
app.use(async(ctx,next)=>{
await next();
ctx.response.type = 'text/html';
ctx.response.body = '<h1>cdda<h1>';
})
依次打印出1 2 3所以可见顺序是看app.use的加载顺序。在await next()执行完毕后才执行下面的语句。
koa中的路由是一个非常重要的概念,在其中根据不同的路由执行不同的逻辑顺序。
使用koa-router
// 注意require('koa-router')返回的是函数:
const router = require('koa-router')();
定义路由
// add url-route:
router.get('/hello/:name', async (ctx, next) => {
var name = ctx.params.name;
ctx.response.body = `<h1>Hello, ${name}!</h1>`;
});
router.get('/', async (ctx, next) => {
ctx.response.body = '<h1>Index</h1>';
});
随后使用router
// add router middleware:
app.use(router.routes());
注意导入
koa-router
的语句最后的
()
是函数调用:
处理post请求。
post请求通常有表单,或者将参数放在body中,但无论是Node.js提供的原始request对象,还是koa提供的request对象,都
不提供
解析request的body的功能! 所以我们用koa-bodyparser来解析。
这里要注意的是。koa-bodyparser必须在router之前被注册到app对象中。
接下来,就可以处理简单的post请求了。
var getuser = async (ctx, next) => {
var
name = ctx.request.body.name || '',
password = ctx.request.body.password || '';
console.log(name);
ctx.response.body = `<h1>Welcome, ${name}!</h1>`;
};
这样就可以简单的处理请求并返回。