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、匹配路由完成以后又会回来执行中间件
    
  • 相关阅读:
    Linux I/O调度
    集群心跳机制
    如何修改集群的公网信息(包括 VIP) (文档 ID 1674442.1)
    AVL树(平衡二叉树)
    二叉搜索树
    二叉树及树的遍历
    python实现基数排序
    python之迷宫BFS
    python之迷宫DFS
    python实现队列
  • 原文地址:https://www.cnblogs.com/jiaoshou/p/13441557.html
Copyright © 2011-2022 走看看