Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

koa源码分析(一) - application.js #5

Open
brunoyang opened this issue Oct 5, 2015 · 4 comments
Open

koa源码分析(一) - application.js #5

brunoyang opened this issue Oct 5, 2015 · 4 comments

Comments

@brunoyang
Copy link
Owner

本文分为四个部分,分别对应源码的四个文件。

仓库:https://github.com/koajs/koa

官网:http://koajs.com/

官方介绍:Koa is a new web framework designed by the team behind Express, which aims to be a smaller, more expressive, and more robust foundation for web applications and APIs. Through leveraging generators Koa allows you to ditch callbacks and greatly increase error-handling. Koa does not bundle any middleware within core, and provides an elegant suite of methods that make writing servers fast and enjoyable.

本文根据koa@1.0.0撰写。

依赖

  • debug:debug源码分析
  • compose_es7:与co.wrap相似,不过能够接受 async/await 函数;
  • onFinished:捕捉finish或error事件,并根据第二个参数执行回调;
  • compose:compose_es7的简化版,只接受generator;
  • isJSON:顾名思义,判断传入参数是否为JSON;
  • statuses:将http码分为三类,redirect、empty以及retry,然后根据传入的http来判断属于哪一类;
  • accepts:根据req的内容判断(content negotiation)字段,如accept,Accept-Encoding,Accept-Language等字段对这些字段进行格式化,方便后续处理;
  • only:只返回在传入参数里所包含的字段;
  • co:co源码解析

源码解析

Application

koi暴露了Application对象作为入口,Application的几个属性挑重要的讲:middlewarecontextrequestresponse会在后续文章里讲到。

middleware

middleware是一个数组,在这里特称为中间件数组,数组元素要求是generator函数。当然开启了experimental就可以用async/await了。

middleware数组是如何工作的可以参考下图

middleware 数组

context

http请求和相应进行包装,得到包含requestresponse的对象,对象所具体包含的内容在下面会有写到。

Application.prototype

Applicationn的prototype继承自event.Emitter的prototype,并挂载了多个方法。

listen

这是http.createServer(app.callback()).listen(...)的简写,重要的是当中的callback函数。

callback函数的第一行就是将response函数作为了middleware数组的第一个元素,所以我们再来看一下response函数。

response函数的第一句,就是个yield *next,也就是说在req进入中间件数组时response函数不作处理。那什么时候处理呢?看一下上面这张图,可以看到,response函数在之后的所有中间件都执行完成后,对res做最后一步的处理。

middleware数组放入compose后,会得到一个generator函数,这个generator函数的效果相当于是将多个中间件组合成一个,来让co可以按顺序执行。最后,传入ctx,完成一次http请求。

createContext

ctx从哪来的呢,是由createContext函数创建的。返回的结果形如下面的代码。requestresponsekoa生成的对象,resreqnode原生的http对象,当需要访问原生对象时,可以通过this.res来访问到,但并不推荐这样做,推荐直接访问request对象。

{
    request: {
        url: '/',
        method: 'GET',
        req: <origin node >
        ...
    },
    response: {

    }
    app: {
        subdomainOffset: 2,
        env: 'development'
    },
    originalUrl: '/',
    req: '<original node req>',
    res: '<original node res>',
    socket: '<original node socket>'
}

inspect/toJSON

返回配置的参数subdomainOffsetenv

@camsong
Copy link

camsong commented Nov 5, 2015

2.0 快出来了,有时间也分析一下吧

@brunoyang
Copy link
Owner Author

@camsong ok 这周末

@tonyjiafan
Copy link

前来拜读

@Calerme
Copy link

Calerme commented May 14, 2018

mark

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants