koa2 从入门到进阶之路 (三)

以前的文章咱们介绍了一下 koa 路由,get 传值,动态路由,本节咱们看一下 koa 中间件 以及 koa 中间件的洋葱图执行流程。前端

1、什么是 Koa 的中间件node

通俗的讲:中间件就是匹配路由以前或者匹配路由完成作的一系列的操做,咱们就能够把它叫作中间件。web

在express中间件(Middleware)是一个函数,它能够访问请求对象(request object (req)), 响应对象(response object (res)), 和 web 应用中处理请求-响应循环流程中的中间件,通常被命名为 next 的变量。在 Koa 中中间件和 express 有点相似。数据库

中间件的功能包括:express

  执行任何代码。后端

  修改请求和响应对象。app

  终结请求-响应循环。koa

  调用堆栈中的下一个中间件。async

若是个人 get、post 回调函数中,没有 next 参数,那么就匹配上第一个路由,就不会往下匹 配了。若是想往下匹配的话,那么须要写 next()编辑器

2、Koa 应用可以使用以下几种中间件:

  应用级中间件

  路由级中间件

  错误处理中间

  第三方中间件

 

咱们先来看一下应用级中间件,咱们仍是按照以前的项目将 app.js 改成以下:

 1 //引入 koa模块
 2 var Koa = require('koa');
 3 var Router = require('koa-router');
 4 
 5 //实例化
 6 var app = new Koa();
 7 var router = new Router();
 8 
 9 //匹配任何路由,若是不写next,这个路由被匹配到了就不会继续向下匹配
10 app.use(async (ctx, next) => {
11     console.log("我是一个中间件");
12     // 当前路由匹配完成之后继续向下匹配
13     await next();
14 });
15 
16 //配置路由
17 router.get('/', async (ctx) => {
18     ctx.body = "首页";
19 });
20 router.get('/news', async (ctx) => {
21     ctx.body = "新闻列页面";
22 });
23 
24 //启动路由
25 app.use(router.routes());
26 app.use(router.allowedMethods());
27 
28 app.listen(3000);

咱们在匹配路由以前写了一个 app.use(async ()=>{}) 的中间件,该中间件若是不像 router.get 那样写一个参数 "/" 或 "/news",那么它将匹配任何一个路由,且最早匹配,若是咱们在其中写 next() 的话,则会终止在此,再也不向下陪陪路由,运行结果以下:

咱们在编辑器的控制台看一下输出日志:

 

接下来咱们看一下路由中间件:

 1 //引入 koa模块
 2 var Koa = require('koa');
 3 var Router = require('koa-router');
 4 
 5 //实例化
 6 var app = new Koa();
 7 var router = new Router();
 8 
 9 //配置路由
10 router.get('/', async (ctx, next) => {
11     console.log("控制台打印");
12     // 当前路由匹配完成之后继续向下匹配
13     await next();
14 });
15 router.get('/', async (ctx) => {
16     ctx.body = "首页";
17 });
18 router.get('/news', async (ctx) => {
19     ctx.body = "新闻列页面";
20 });
21 
22 //启动路由
23 app.use(router.routes());
24 app.use(router.allowedMethods());
25 
26 app.listen(3000);

在上面的代码中咱们定义了两个 router.get('/',  ) 的路由,第一个咱们在控制台输出一句话,第二个咱们想页面输出内容。若是在第一个里面咱们不写 next() 方法的话,则不会进入第二个里面,结果以下:

控制台打印结果

 

接下来咱们看一下错误处理中间件:

 1 //引入 koa模块
 2 var Koa = require('koa');
 3 var Router = require('koa-router');
 4 
 5 //实例化
 6 var app = new Koa();
 7 var router = new Router();
 8 
 9 //匹配任何路由,若是不写next,这个路由被匹配到了就不会继续向下匹配
10 app.use(async (ctx,next)=>{
11     await next();
12     //若是页面找不到
13     if(ctx.status==404){
14         ctx.status = 404;
15         ctx.body="404 页面"
16     }
17 });
18 
19 //配置路由
20 router.get('/', async (ctx) => {
21     ctx.body = "首页";
22 });
23 router.get('/news', async (ctx) => {
24     ctx.body = "新闻列页面";
25 });
26 
27 //启动路由
28 app.use(router.routes());
29 app.use(router.allowedMethods());
30 
31 app.listen(3000);

咱们还按以前的应用中间件那样写,而后在里面作了一个 if 语句判断,当页面响应时,会给后端返回一个 status 码,这个就不在单独说了,若是这个 status 报 404,咱们知道表示该页面不存在,那么咱们就能够拦截 next() 方法,输出给前端一个 404 页面,结果以下:

咱们匹配了一个 "/news" 路由,能够正常显示内容,若是咱们不当心少写一个 "s",写成了 "new",结果以下:

在上面的代码中咱们是将 if 判断语句放在了 next() 方法以后,那能不能放在 next() 以前呢?这个问题咱们在下面的 koa 中间件流程控制中再详细说明。

 

第三方中间件在以后的文章中咱们用到了第三方模块时再说。

接下来我么看一下 koa 中的中间件流程控制。

koa被认为是第二代node web framework,它最大的特色就是独特的中间件流程控制,是一个典型的洋葱模型。

 

上面的两张图能够很直观的说明 koa 中的中间件流程控制。咱们接下来用代码演示一下:

 1 //引入 koa模块
 2 var Koa = require('koa');
 3 var Router = require('koa-router');
 4 
 5 //实例化
 6 var app = new Koa();
 7 var router = new Router();
 8 
 9 app.use(async (ctx, next) => {
10     console.log('一、这是第一个中间件01');
11     await next();
12     console.log('五、匹配路由完成之后又会返回来执行中间件');
13 });
14 
15 app.use(async (ctx, next) => {
16     console.log('二、这是第二个中间件02');
17     await next();
18     console.log('四、匹配路由完成之后又会返回来执行中间件');
19 });
20 
21 router.get('/', async (ctx) => {
22     console.log('三、匹配到了news这个路由');
23     ctx.body = "首页";
24 });
25 
26 //启动路由
27 app.use(router.routes());
28 app.use(router.allowedMethods());
29 
30 app.listen(3000);

咱们在上面的代码引用了两个应用级的中间件,分别在 next() 先后输出日志,当咱们访问 localhost:3000/ 时,咱们看一下控制台的输出结果:

从输出打印结果顺序咱们能够看出中间件会先逐级处理 request  请求,而后再返回来逐级处理 response 请求,这就是咱们为何要将 错误处理中间件 中的 if 判断语句放在 next() 方法以后,这样就是在路由进入 "/news" 后返回 status = 404 的结果后再进行处理,若是放在了 next() 方法以前,则会直接判断 if 语句,不会再向下匹配 "/news" 路由了。好比咱们的用户登陆系统就能够这么用,当用户输入帐号密码后出入后台,后台在数据库匹配以后再进行处理,处理以后返回给前端,就是这么玩的。

相关文章
相关标签/搜索