zoukankan      html  css  js  c++  java
  • 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、匹配路由完成以后又会回来执行中间件
    
  • 相关阅读:
    【故障处理】ORA-12162: TNS:net service name is incorrectly specified (转)
    android studio 编程中用到的快捷键
    java时间格式串
    android Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine.
    linux安装vmware
    x1c 2017 安装mint18的坑——grub2
    x1c2017 8G版 win linux的取舍纠结记录
    python的try finally (还真不简单)
    kafka+docker+python
    json文件不能有注释
  • 原文地址:https://www.cnblogs.com/jiaoshou/p/13441557.html
Copyright © 2011-2022 走看看