Fork me on GitHub

Koa.js 2.x 学习笔记

记录笔者日常学习笔记,无深解内容,除了笔者无人看懂。
Koa.js
Koa-router 学习笔记

简介

koa 是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函数嵌套,并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。

安装

Koa需要 node v7.6.0或更高版本来支持ES2015、异步方法

新建一个测试目录,然后执行 npm init 生成package.json配置文件。
执行koa安装

npm i koa

新建一个app.js文件

const Koa = require('koa');
const app = new Koa();

app.use(async ctx => {
  ctx.body = 'Hello World';
});

app.listen(3000);

执行node命令,运行项目

 node my-koa-app.js

访问http://localhost:3000/ 就可以看到Hello World

中间件

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

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

中间件的功能包括:

  • 执行任何代码
  • 修改请求和响应请求对象
  • 终结请求-响应循环
  • 调用堆栈中的下一个中间件

如果get、post回调函数中,没有next参数,那么就匹配上第一个路由,就不会往下匹配了。如果想往下匹配的话,那么就需要写next()。

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

  • 应用级中间件
  • 路邮级中间件
  • 错误处理中间件
  • 第三方中间件

可以写两个参数,第一个是匹配的路径,第二个是回调函数,第一个参数可以省略

app.use('/',function(){});

不管app.userouter的书写顺序如何,都是先执行app.use再执行router

应用级中间件

// 引入Koa模块
const Koa = require('koa');
// 引入Koa-router
const Router = require('koa-router');

// 实例化Koa模块
const app = new Koa();
// 实例化路由模块
const router = new Router();

// Koa 中间件
// app.use('/',function(){});   //可以写两个参数,第一个是匹配的路径,第二个是回调函数,第一个参数可以省略

// 匹配任何路由,如果不写next,这个路由被匹配到了就不会继续向下匹配了
// app.use(async (ctx)=>{
//   ctx.body = '这是一个中间件';
// });

// 应用级中间件
// 匹配任何路由之前打印日期
app.use(async (ctx,next)=>{
  console.log(new Date());
  await next();  //当前路由匹配完成以后继续向下匹配
});

// 配置路由
// ctx 上下文 context,  包含了request和response等信息
router.get('/',async (ctx)=>{
  ctx.body = '网站首页';  //返回数据    相当于:原生里面的res.writeHead()  res.end()
}).get('/news',async (ctx)=>{
  ctx.body = '新闻列表页面';
}).get('/login',async (ctx)=>{
  ctx.body = '网站登录页面';
});

// 启动路由
app
  .use(router.routes())   /*启动路由*/
  .use(router.allowedMethods());  //作用:当请求出错时处理逻辑
/*
 * router.allowedMethods()作用: 这是官方文档的推荐用法,我们可以
 * 看到 router.allowedMethods()用在了路由匹配 router.routes()之后,所以在当所有
 * 路由中间件最后调用.此时根据 ctx.status 设置 response 响应头 
 *
 */

// 监听3000端口
app.listen(3000,()=>{
  console.log('starting at port 3000');
});

路由级中间件

// 引入Koa模块
const Koa = require('koa');
// 引入Koa-router
const Router = require('koa-router');

// 实例化Koa模块
const app = new Koa();
// 实例化路由模块
const router = new Router();

// Koa 中间件
// app.use('/',function(){});   //可以写两个参数,第一个是匹配的路径,第二个是回调函数,第一个参数可以省略

// 匹配任何路由之前打印日期
app.use(async (ctx,next)=>{
  console.log(new Date());
  await next();  //当前路由匹配完成以后继续向下匹配
});

// 配置路由
// ctx 上下文 context,  包含了request和response等信息
router.get('/',async (ctx)=>{
  ctx.body = '网站首页';  //返回数据    相当于:原生里面的res.writeHead()  res.end()
});

// 路由级中间件
// 匹配带news路由以后继续向下匹配路由
router.get('/news',async (ctx,next)=>{
  console.log('这是一个新闻路由');
  await next();
});
router.get('/news',async (ctx)=>{
  ctx.body = '新闻列表页面';
});

router.get('/login',async (ctx)=>{
  ctx.body = '网站登录页面';
});

// 启动路由
app
  .use(router.routes())   /*启动路由*/
  .use(router.allowedMethods());  //作用:当请求出错时处理逻辑
/*
 * router.allowedMethods()作用: 这是官方文档的推荐用法,我们可以
 * 看到 router.allowedMethods()用在了路由匹配 router.routes()之后,所以在当所有
 * 路由中间件最后调用.此时根据 ctx.status 设置 response 响应头 
 *
 */

// 监听3000端口
app.listen(3000,()=>{
  console.log('starting at port 3000');
});

错误处理中间件
Koa是从第一个中间件开始执行,遇到 await next() 就进入下一个中间件,一直到执行到最后一个中间件。然后再逆序执行上一个中间件 await next() 后面的代码,一直到第一个中间件 await next() 后面的代码执行完毕才发出响应。

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

app.use(async (ctx, next) => {
    console.log('1'); 
    await next(); // 调用下一个middleware
    console.log('5')
});

app.use(async (ctx, next) => {
    console.log('2');
    await next(); // 调用下一个middleware
    console.log('4');
});

app.use(async (ctx, next) => {
    console.log('3');
});

输出结果: 12345

在这个例子里,通过输出结果可以看出三个中间件的执行顺序是:
中间件1 -> 中间件2 -> 中间件3 -> 中间件2 -> 中间件1

koa 中间件的执行流程,如下代码访问/news路由

// 引入Koa模块
const Koa = require('koa');
// 引入Koa-router
const Router = require('koa-router');

// 实例化Koa模块
const app = new Koa();
// 实例化路由模块
const router = new Router();

// Koa 中间件
// app.use('/',function(){});   //可以写两个参数,第一个是匹配的路径,第二个是回调函数,第一个参数可以省略

// 因为不管app.use 和router 的书写顺序是怎样的,都会先执行app.use,所以这个写在开头和写在结尾效果都是一样的
app.use(async (ctx,next)=>{
  console.log('1、这是第一个中间件');
  await next();  //当前路由匹配完成以后继续向下匹配
  console.log('5、匹配路由完成以后又会回来执行中间件');
});
app.use(async (ctx,next)=>{
  console.log('2、这是第二个中间件');
 await next();  //当前路由匹配完成以后继续向下匹配
  console.log('4、匹配路由完成以后又会回来执行中间件');
});
// 配置路由
// ctx 上下文 context,  包含了request和response等信息
router.get('/',async (ctx)=>{
    console.log('网站首页');
    ctx.body = '网站首页';  //返回数据    相当于:原生里面的res.writeHead()  res.end()
});

router.get('/news',async (ctx)=>{
  console.log('3、匹配到了这个新闻列表页面');
  ctx.body = '新闻列表页面';
});

router.get('/login',async (ctx)=>{
  console.log('网站登录页面');
  ctx.body = '网站登录页面';
});

// 启动路由
app
  .use(router.routes())   /*启动路由*/
  .use(router.allowedMethods());  //作用:当请求出错时处理逻辑
/*
 * router.allowedMethods()作用: 这是官方文档的推荐用法,我们可以
 * 看到 router.allowedMethods()用在了路由匹配 router.routes()之后,所以在当所有
 * 路由中间件最后调用.此时根据 ctx.status 设置 response 响应头 
 *
 */

// 监听3000端口
app.listen(3000,()=>{
  console.log('starting at port 3000');
});

打印结果:

1、这是第一个中间件
2、这是第二个中间件
3、匹配到了这个新闻列表页面
4、匹配路由完成以后又会回来执行中间件
5、匹配路由完成以后又会回来执行中间件
posted @ 2019-08-05 17:57  较瘦  阅读(162)  评论(0编辑  收藏  举报
知识点文章整理