koa源码由浅入深解析

koa源码解析

koa主要分红5个部分的概念,

  • Application
  • context
  • request
  • response
  • middleware

以上5个概念应该仍是很好理解的vue

首先把koa给下载下来了,能够看到这里有四个文件,这里我主要讲下application,也就是最核心的一个模块 node

这里核心模块是application文件,从开始提及吧app

const Emitter = require("events");
class Koa2 extends Emitter {
  constructor() {
    super();
    this.middleware = [];
    this.context = Object.create(context);
    this.request = Object.create(request);
    this.response = Object.create(response);
  }
  /** * 监听listen */
  listen(...args) {
    
  }
  /** * 回调函数 */
  callback() {
    
  }
  /** * 使用插件 * @param {} fn */
  use(fn) {
    
  }
}
复制代码

以上咱们经常使用的是一些接口,从这些东西入手吧,这里继承了emitter这个构造函数,也就是node里面的事件监听,用过的人应该使用过下面这种koa

const app = new Koa2
app.on("error",()=>{

})
复制代码

看到这里大概就明白了为何要继承emitter,主要是为了实现事件分发async

第二步吧 use函数

这里很简单,其实就是把use中的函数加到中间件队列中,都应该能理解了函数

/** * 使用插件 * @param {} fn */
  use(fn) {
    this.middleware.push(fn);
    return this;
  }
复制代码

看到第三步 listen函数,将中间件的方法加入到callback中

这里至关因而一个语法糖ui

/** * 监听listen */
  listen(...args) {
    let server = http.createServer(this.callback());
    server.listen(...args);
  }
    /** * 回调函数 */
  callback() {
    const fn = conpose(this.middleware); //中间件的实现方式
    // if (!this.listenerCount('error')) this.on('error', this.onerror);
    const handleRequest = (req, res) => {
      const ctx = this.createContext(req, res);
      return this.handleRequest(ctx, fn);
    };
    return handleRequest;
  }
复制代码

这里将全部的中间件聚合成一个函数,这里聚合使用的是conpose,也就是koa的中间件洋葱模型this

中间件 也就是koa的中间件洋葱模型,你们能够本身去查查

众所周知,koa是使用async的, 这里说的,这里的dispatch至关于next的意思吧!进入spa

module.exports = function(middleware) {
  return function(ctx, next) {
    // let index = -1;
    return dispatch(0);
    function dispatch(i) {
      let fn = middleware[i];
      if (i === middleware.length) {
        fn = next
      }
      if(!fn) {
        return Promise.resolve()
      }
      try {
        return Promise.resolve(fn(ctx, dispatch.bind(null, i + 1)));
      } catch (error) {
        return Promise.reject(error)
      }
    }
  };
};
复制代码

再回来看callback这个函数插件

callback() {
    const fn = conpose(this.middleware); //中间件的实现方式
    // if (!this.listenerCount('error')) this.on('error', this.onerror);
    const handleRequest = (req, res) => {
      const ctx = this.createContext(req, res);
      return this.handleRequest(ctx, fn);
    };
    return handleRequest;
  }
  handleRequest(ctx, middleware) {
    return middleware(ctx).then(() => {
      console.log("中间件执行结束");
      // 这里能够拿到中间件里面修改的数据等
      /* 如ctx.response.body({ }) */
      return ctx.response.res.end("hello");
    });
  }
  /** * 建立上下文 */
  createContext(req, res) {
    // let ctx = {}
    const context = Object.create(this.context);
    context.request = Object.create(this.request);
    context.response = Object.create(this.response);
    context.app = this;
    context.response.res = res;
    context.request.req = req;
    return context;
  }
复制代码

reqres是http.createServer()的回调函数,这里就很少说了 下面的重点是建立一个上下文createContext

这里就连接到Object.create(this.context)等, 其实也就是将context,request,response实例化,将callback里面回传的request,response重写了一下,而且提供了一些方法 Object.create(this.request)Object.create(this.response) 就不细说了,都是封装一些方法,封装一些返回的值

进入到context文件,咱们能够看到下面的这样一个函数调用,其实就是一个数据劫持

delegate(proto, 'response')
  .method('attachment')
  .method('redirect')
  .method('remove')
  .method('vary')
  .method('set')
  .method('append')
  .method('flushHeaders')
  .access('status')
  .access('message')
  .access('body')
  .access('length')
  .access('type')
  .access('lastModified')
  .access('etag')
  .getter('headerSent')
  .getter('writable');
复制代码

打个比方说ctx.body,其实就是ctx.response.body 这里作了一层代理,好处的话,能够不用污染ctx,而且不须要建立两份变量,这里能够去看看vue的data是怎么作的,为何在this中能访问到data中的变量,这里是同样的

以上就是主要的koa内容了,至于其余都是开发中间件了 最后还有一个点 就是inspect,你看代码的时候会看到在生命对象和构造函数的时候都用到了这个inspect

举个例子哈!

const proto = {
  inspect(){
    return "hello inspect";
  }
}
if (util.inspect.custom) {
  proto[util.inspect.custom] = proto.inspect;
}
let a = Object.create(proto)

console.log(a)
// 输出 "hello inspect"
复制代码

koa里面用到,我理解的意思是,在打印的时候只打印出本身想打印出来的 ,别的不打印,其余就本身体会了。

相关文章
相关标签/搜索