Koa源码学习(1)

感觉代码不多,就生看代码了,从application.js开始。

debug

1
const debug = require('debug')('koa:application'); // >>: debug usage, brilliant

这个库的使用,看起来还是很不错的,可以控制输出哪些debug信息,以后项目中可以用下

customize打印application对象

1
2
3
if (util.inspect.custom) { // >>: inspect
this[util.inspect.custom] = this.inspect;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* Return JSON representation.
* We only bother showing settings.
*
* @return {Object}
* @api public
*/
toJSON() {
return only(this, [
'subdomainOffset',
'proxy',
'env'
]);
}
/**
* Inspect implementation.
*
* @return {Object}
* @api public
*/
inspect() {
return this.toJSON();
}

因为还有context,request,response等对象,可能并没有toString的方法,就不输出它们,这里定制的方式值得学习一下:this[util.inspect.custom] = this.inspect

use()

就是简单的把中间件放到自己的middleware中:

1
this.middleware.push(fn);

callback()

koa的listen其实就是:

1
2
const server = http.createServer(this.callback());
return server.listen(...args);

自己的东西的注入,都是在callback()里完成的

node文档:

http.createServer([options][, requestListener])
The requestListener is a function which is automatically added to the 'request' event.

意思大概就是,每次有request时间,都会调用这个函数吧。

在里边封装了自己的处理方式:

1
2
3
4
5
6
const handleRequest = (req, res) => {
const ctx = this.createContext(req, res);
return this.handleRequest(ctx, fn);
};
return handleRequest;

compose()

嗯,其实就是把所有的中间件串起来,Promise的使用,自己还是需要学习啊

createContext(req, res)

对原来的requestresponse的一个封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.state = {};
return context;
}

其实还是很简单的,就主要是几个绑定,互相绑一绑,然后和node原来的req, res绑一绑

handleRequest(ctx, fn)

1
2
3
4
5
6
7
8
handleRequest(ctx, fnMiddleware) {
const res = ctx.res;
res.statusCode = 404;
const onerror = err => ctx.onerror(err);
const handleResponse = () => respond(ctx);
onFinished(res, onerror);
return fnMiddleware(ctx).then(handleResponse).catch(onerror);
}

其实有些看不太懂…

为什么,要用handleResponse而不直接用respond,为什么用ctx,而不用middleware处理之后的ctx

为什么要有onFinish(),感觉并不会有什么用

respond

这个helper function,里边就是各种对不同情况的处理,这个看具体response的源码的时候再说吧


嗯,感觉看完application.js,也就那么回事,就是处理中间件,而已,可能这就是Koa有趣的地方吧,精简的核心,统一的接口,无限可能的拓展。