美文网首页
express 和 koa

express 和 koa

作者: 看到这朵小fa了么 | 来源:发表于2020-03-31 10:05 被阅读0次

express

  • req.cookies cookie-parser 处理cookie挂载
  • req.query, req.body拦截请求参数
  • express.json() 转化json (解析json格式的请求参数,赋值到req.body,返回参数json格式)
  • express.urlencoded() 解析req 其他格式的数据
  • express-session connect-redis
  • morgan 输出日志 通过文件流写入日志(flags: 'a') ,配置参数:https://github.com/expressjs/morgan
  • router=express.Router()
  • app.use(命中, 回调中间件)

中间件

  • 中间件用于帮助我们做一些繁琐的基本工作,如路由匹配(koa-router),参数提取(koa-bodypaser),响应json数据(koa-json),支持跨域(koa-cors),保持用户登录状态(koa-session/koa-jwt)
  • 中间件的设计,专注于解决一个问题,通过中间件的组合来实现功能的拓展
  • 中间件运行,尾调用的洋葱模型

express和koa的区别

  • koa不在内核中绑定任何中间件,express则内置了一些功能如express.Router()
  • koa原生支持async await 相比于promise处理异步回调更加优雅
  • 最重要的是两者对异步的中间件调用顺序是不同的,express不会等待中间件的异步处理执行完毕,主要是由于内部是通过回调函数的组合,其next的机制导致不会等待异步的完成而继续执行同步操作,当然对于一个中间件的内部使用了async await,执行顺序还是正确的;
    而koa它的next机制是利用闭包和递归的性质,一个个执行中间件,并且每次执行都是返回promise的封装,再结合generator状态机,实现同步异步的按顺序执行

中间件的实现

  • express
    脚手架:express
    1、分解来看 有use get post方法可以注册路由 listen进行监听
    2、注册路由时需要对参数进行匹配,分解为path和对应的中间件列表作为对象存储
    3、listen监听注册回调函数处理中间件
    4、中间件的收集需要匹配方法和路径
    6、中间件的触发,需要调用next函数进行依次触发
    7、repress-session; require('connect-redis')(session)
  • koa
    koa1 用generator实现
    koa2 async await实现 结合node8+支持 实现更加完美
    脚手架 npm i koa-generator; koa2初始化
    1、koa-router; router.prefix(/)
    2、中间件必须以async开头,保证next执行顺序,通过await等待异步的执行
    3、ctx封装了request和response
    3、返回值可以直接赋值给ctx.body 不需要处理json格式和异步回调promise返回
    4、koa-generic-session koa-redis
    5、实现koa无需考虑路径匹配,主要在于回调函数的处理,需要对中间件进行promise的包装,保证执行顺序
    6、ctx的参数包装
// 简单实现express

const http = require("http");
const slice = Array.prototype.slice;

class LikeExpress {
  constructor() {
    this.routes = {
      all: [],
      get: [],
      post: []
    };
  }

  register() {
    let info = {};
    if (typeof arguments[0] === "string") {
      info.path = arguments[0];
      info.stack = slice.call(arguments, 1);
    } else {
      info.path = "/";
      info.stack = slice.call(arguments, 0);
    }
    return info;
  }
  use() {
    let result = this.register.apply(this, arguments);
    this.routes.all.push(result);
    console.log('all', this.routes.all)
  }
  get() {
    let result = this.register.apply(this, arguments);
    this.routes.get.push(result);
  }
  post() {
    let result = this.register.apply(this, arguments);
    this.routes.post.push(result);
  }
  match(method, url) {
    
    let resultList = [];
    let stack = [];
    stack = stack.concat(this.routes.all);
    stack = stack.concat(this.routes[method]);
    if (url === "favicon.icon") {
      return resultList;
    }
    for (let item of stack) {
      if (item.path.indexOf(url) === 0) {
        resultList = resultList.concat(item.stack);
      }
    }
    console.log('resut', resultList)
    return resultList;
  }
  handler(req, res, list) {
    const next = () => {
      let middleware = list.shift();
      if (typeof middleware === 'function') {
        middleware(req, res, next);
      }
    };
    next();
  }
  callback() {
    return (req, res) => {
      res.json = (data) => {
        res.setHeader("Content-type", "application/json");
        res.end(JSON.stringify(data));
      };
      let url = req.url;
      let method = req.method.toLowerCase();
      let resultList = this.match(method, url);
      console.log('list', resultList)
      this.handler(req, res, resultList);
    };
  }
  listen(...args) {
    let server = http.createServer(this.callback());
    server.listen(...args);
  }
}

module.exports = () => {
  return new LikeExpress();
};

// 简单koa2实现 主要是promise对象的包装
const http = require("http");

// 组合中间件
function compose(middlewareList) {
    return function(ctx) {
        function dispath(i) {
           const fn = middlewareList[i]
           try {
               return Promise.resolve(
                   fn(ctx, dispath.bind(null, i+1))
               )
           } catch (err) {
               return Promise.reject(err)
           }
        }
        return dispath(0)
    }
}
class LikeKoa2 {
  constructor() {
    this.middlewareList = [];
  }

  use(fn) {
    this.middlewareList.push(fn);
    return this;
  }
  createContent(req, res) {
      const ctx = {
          req, res
      }
      ctx.query = req.query
      return ctx
  }
  handler(ctx, fn) {
      return fn(ctx)
  }
  callback() {
      const fn = compose(this.middlewareList)
      return (req, res, next)=> {
         const ctx = this.createContent(req, res)
         return this.handler(ctx, fn)
      }
  }
  listen(...args) {
    let server = http.createServer(this.callback());
    server.listen(...args);
  }
}

module.exports = () =>{
    return new LikeKoa2()
}


相关文章

  • koa-router的使用

    Koa中的路由和Express不同,Express是把路由集成在Express中,Koa则需要通过kao-rout...

  • node学习三(koa使用入门)

    express和koa文档: express: http://www.expressjs.com.cnkoa: h...

  • koa中间件-express中间件

    node开启http服务 koa开启http服务 express中间件 koa与express

  • koa入门

    koa介绍 Koa是由Express背后的团队创建的新流行的Web应用框架。它旨在成为Express的现代和极简主...

  • express 和 koa

    express req.cookies cookie-parser 处理cookie挂载 req.query, r...

  • express和koa的区别

    express和koa从整体上来看,koa是比express更加轻量,他没有内置的各种中间件的支持,更集中于请求处...

  • koa2 入门教程

    koa koa 中文koa-generator 简介 koa 是一个新的 web 框架, 由 express 原班...

  • koa.js的使用(koa2)

    koa与Express简单比较Express connect 中间件 封装了 路由、视图,koa co中间件 不包...

  • Express源码书写

    Express基本使用 express是一个函数,koa是类 express中的中间件可以放置路径,路径的规则和c...

  • 3.koa框架 / koa-router / koa-views

    koa介绍 网址:koa.bootcss.com koa是express原班人马打造的轻量、健壮、富有表...

网友评论

      本文标题:express 和 koa

      本文链接:https://www.haomeiwen.com/subject/mxgzictx.html