您的位置:首页 > Web前端 > Node.js

Node.js-koa入门

2017-08-17 14:00 351 查看
摘要 - 廖雪峰JavaScript教程

创建一个koa2工程

首先,我们创建一个
test
目录,并在目录里面创建一个
koa.js
文件,输入以下代码:

// 导入的是koa2,不是koa1,koa2是一个class类,所以大写。
const Koa = require('koa')

// 创建一个web app 实例
const app = new Koa()

// 对于任何请求,都执行该回调函数
app.use(async (ctx, next) => {
await next()
ctx.response.type = 'text/html'
ctx.response.body = '<h1> Hello Koa2 </h1>'
})

// 监听9000端口
app.listen(9000, () => {
console.log('Server is running and the port is 9000 ')
})


其中,参数
ctx
是koa传入的封装了
response
resquest
的变量,
next
是koa要处理的下一个异步函数。

上面的异步函数中,我们首先用
await next( )
处理下一个异步函数,然后设置
Content-Type
和内容。

async
标记的函数称为异步函数,在异步函数中,可以用
await
调用另一个异步函数,这两个关键字在ES7中引入。

注意:要是想运行上面的代码,请使用最新的node7以后的版本,因为低版本的node不支持
async
await
关键,或者你可以
babel
进行转成es5进行运行。

koa middleware

让我们在仔细看下koa的执行逻辑。核心代码是:

app.use(async (ctx, next) => {
await next()
ctx.response.type = 'text/html'
ctx.response.body = '<h1> Hello Koa2 </h1>'
})


每收到一个
http
请求,koa就会调用通过
app.use()
注册的异步函数,并传入
ctx
next
参数。

我们可以对
ctx
操作,并设置返回内容。但是为什么要调用
await next()


原因是koa把很多
async
函数组成一个处理链,每个
async
函数都可以做一些自己的事情,然后用
await next()
来调用下一个
async
函数。我们把每个
async
函数称为
middleware
,这些
middleware
可以组合起来,完成很多有用的功能。

例如,可以用以下3个
middleware
组成处理链,依次打印日志,记录处理时间,输出HTML:

app.use(async (ctx, next) => {
console.log(`${ctx.request.method} ${ctx.request.url}`); // 打印URL
await next(); // 调用下一个middleware
});

app.use(async (ctx, next) => {
const start = new Date().getTime(); // 当前时间
await next(); // 调用下一个middleware
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>Hello, koa2!</h1>';
});


middleware
的顺序很重要,也就是调用
app.use()
的顺序决定了
middleware
的顺序。

此外,如果一个
middleware
没有调用
await next()
,会怎么办?答案是后续的
middleware
将不再执行了。这种情况也很常见,例如,一个检测用户权限的
middleware
可以决定是否继续处理请求,还是直接返回403错误:

app.use(async (ctx, next) => {
if (await checkUserPermission(ctx)) {
await next();
} else {
ctx.response.status = 403;
}
});


理解了
middleware
,我们就基本会用koa了!

最后注意
ctx
对象有一些简写的方法,例如
ctx.url
相当于
ctx.request.url
ctx.type
相当于
ctx.response.type
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: