koa源码

栏目: Node.js · 发布时间: 8年前

内容简介:koa源码

写在前面

本文将会大家来看下 koa 的源码,当然本文需要大家了解 koa 的中间件机制,如果大家之前没有了解过其实现原理,可以关注下 这篇文章

koa 的源码非常的精简,与 express 不同, koa 只是为开发者搭起了一个架子,没有任何的功能,包括路由,全部由中间件实现;下面就来看下 koa 的实现:

koa

创建应用时,一般都会利用 app.listen 指定一个端口号,这个方法的本质就是 http.createServer

listen() {
    debug('listen');
    const server = http.createServer(this.callback());
    return server.listen.apply(server, arguments);
}

最为关键的就是这个 callback 的实现:

koa源码

callback() {
    const fn = compose(this.middleware);

    if (!this.listeners('error').length) this.on('error', this.onerror);

    const handleRequest = (req, res) => {
        res.statusCode = 404;
        const ctx = this.createContext(req, res);
        const onerror = err => ctx.onerror(err);
        const handleResponse = () => respond(ctx);
        onFinished(res, onerror);
        return fn(ctx).then(handleResponse).catch(onerror);
    };

    return handleRequest;
}

需要注意下面几点:

  • onFinished(res, onerror) ,应对的是返回的 bodyStream 的情况,为其添加一个 finished 事件。

  • respond() 根据 ctxstatus,body,method 来决定如何响应这次请求:

    • status204,304 ,不需要有响应体, res.end() 就好

    • methodHEADHEAD 的意义是不请求资源内容但是需要了解资源情况,所以只需要请求头,指定了资源 lengthres.end() 就好

    • 加入 body 为空,则 bodystatuses 包中 status 对应的文字描述,如 404 => Not Found

context对象

koarequest 对象 response 封装成了一个对象,提供了一些别名,具体可以参见 context对象 ,例如:当访问 ctx.url 实则是访问的 ctx.request.url 。具体的实现利用了tj写的 delegates 这个 npm 包来对 context 对象添加属性, koa 中利用了其中三个 api :

  • method :添加方法引用

  • getter :利用 __defineGetter__ ,添加 getter 属性

  • access :添加 gettersetter

对于 context 创建的代码:

createContext(req, res) {
    const context = Object.create(this.context);
    const request = context.request = Object.create(this.request);
    const response = context.response = Object.create(this.response);
    context.app = request.app = response.app = this;
    context.req = request.req = response.req = req;
    context.res = request.res = response.res = res;
    request.ctx = response.ctx = context;
    request.response = response;
    response.request = request;
    context.originalUrl = request.originalUrl = req.url;
    context.cookies = new Cookies(req, res, {
      keys: this.keys,
      secure: request.secure
    });
    request.ip = request.ips[0] || req.socket.remoteAddress || '';
    context.accept = request.accept = accepts(req);
    context.state = {};
    return context;
  }

函数的参数 req, res 为node本身的对象, requestresponse 分别是对于 reqres 的封装,读取 ctx.url 的过程如下:

koa源码

context 就是一个顶层对象, koa 中,所有的属性和操作基本会基于这个对象,这个对象的组成如下图:

koa源码

写在最后

个人感觉 koa 就像是一个架子,提供了基础的方法和属性,如 ctx.redirect 等,具体的功能主要利用中间件来实现,与 express 相比, koa 去除内置路由, views 等,变得更加的轻量;当然我认为更加重要的是避免了层层回调的出现。以上内容如有出错,欢迎大家指出。


以上所述就是小编给大家介绍的《koa源码》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Data Mining

Data Mining

Jiawei Han、Micheline Kamber、Jian Pei / Morgan Kaufmann / 2011-7-6 / USD 74.95

The increasing volume of data in modern business and science calls for more complex and sophisticated tools. Although advances in data mining technology have made extensive data collection much easier......一起来看看 《Data Mining》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具