You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
app.use = function(fn){
if (!this.experimental) {
// es7 async functions are not allowed,
// so we have to make sure that `fn` is a generator function
assert(fn && 'GeneratorFunction' == fn.constructor.name, 'app.use() requires a generator function');
}
debug('use %s', fn._name || fn.name || '-');
this.middleware.push(fn);
return this;
};
在 callback 中输出错误信息:
app.callback = function(){
if (this.experimental) {
console.error('Experimental ES7 Async Function support is deprecated. Please look into Koa v2 as the middleware signature has changed.')
}
var fn = this.experimental
? compose_es7(this.middleware)
: co.wrap(compose(this.middleware));
//省略
};
compose 的全名叫 koa-compose,它的作用是把一个个不相干的中间件串联在一起:
// 有3个中间件
this.middlewares = [function *m1() {}, function *m2() {}, function *m3() {}];
// 通过compose转换
var middleware = compose(this.middlewares);
// 转换后得到的middleware是这个样子的
function *() {
yield *m1(m2(m3(noop())))
}
var app = require('koa')();
var Router = require('koa-router');
var myRouter = new Router();
myRouter.get('/', function *(next) {
this.response.body = 'Hello World!';
});
app.use(myRouter.routes());
app.listen(4000);
Koa 是一个类似于 Express 的Web开发框架,创始人也都是TJ。Koa 的主要特点是,使用了 ES6 的 Generator 函数,进行了架构的重新设计。Koa 的原理和内部结构很像 Express,但是语法和内部结构进行了升级。
创建Koa应用
创建一个 koa 非常简单:
或者可以酱紫:
这两种方式在 koa 内部是等价的,在 Application 模块中,
listen
就会调用自身的callback
:callback
返回的函数会作为server
的回调:callback
也会将多个中间件转成了一个fn
,在构建服务器函数时方便调用。状态码默认是 404,即没有任何中间件修改过就是 404。每个请求都会通过
createContext
创建一个上下文对象,其参数则分别是 Node 的request
对象和response
对象:对于接收的参数,在返回上下文
context
之前,koa 会将参数注入到自身的request
对象和response
对象上,ctx.request
和ctx.response
返回的是 koa 的对应对象,ctx.req
和ctx.res
返回的是 Node 的对应对象;同时也会将 app 注册到 context/respose/request 对象上,方便在各自的模块中调用:上下文:context
context 对象是 Koa context 模块扩展出来的,添加了诸如 state、cookie、req、res 等属性。
onFinished 是一个第三方函数,用于监听 http response 的结束事件,执行回调。如果找到
context.onerror
方法,这是 koa默认的错误处理函数,它处理的是错误导致的异常结束。错误的处理是在callback
中监听的:koa 本身是没有定义事件处理机制的,其事件处理机制继承自 Node 的
events
:默认的错误分发是在 Context 模块中:
此外,在 Context 模块中,还将
request
对象和response
对象的一些方法和属性委托给了context
对象:通过第三方模块
delegate
将 koa 在 Response 模块和 Request 模块中定义的方法委托到了context
对象上,所以以下的一些写法是等价的:在
createContext
方法中,还给context
定义了重要属性state
这个属性可以被各个中间件共享,用于在中间件之间传递数据,这也是 koa 推荐的方式:
中间件
中间件是对 HTTP 请求进行处理的函数,对于每一个请求,都会通过中间件进行处理。在 koa 中,中间件通过
use
进行注册,且必须是一个 Generator 函数(未开启this.experimental
):输出如下:
与 Express 的中间件顺序执行不同,在koa中,中间件是所谓的“洋葱模型”或级联式(Cascading)的结构,也就是说,属于是层层调用,第一个中间件调用第二个中间件,第二个调用第三个,以此类推。上游的中间件必须等到下游的中间件返回结果,才会继续执行。
koa 对中间件的数量并没有限制,可以随意注册多个中间件。但如果有多个中间件,只要有一个中间件缺少
yield next
语句,后面的中间件都不会执行:上面代码中,因为第二个中间件少了yield next语句,第三个中间件并不会执行。
如果想跳过一个中间件,可以直接在该中间件的第一行语句写上
return yield next
:koa中,中间件唯一的参数就是
next
。如果要传入其他参数,必须另外写一个返回 Generator 函数的函数。this.experimental
是为了判断是否支持es7,开启这个属性之后,中间件可以传入async函数:但 koa 默认是不支持 es7 的,如果想支持,需要在代码中明确指定
this.experimental = true
在
callback
中输出错误信息:compose 的全名叫 koa-compose,它的作用是把一个个不相干的中间件串联在一起:
从上述的
use
的实现可知,由于use
的每次调用均会返回this
,因而可以进行链式调用:路由处理
koa自身有
request
对象和response
对象来处理路由,一个简单的路由处理如下:也可以通过
this.request.headers
来获取请求头。由于没有对响应头做设置,默认响应头类型是text/plain
,可以通过response.set
来设置:上面代码中,每一个中间件负责部分路径,如果路径不符合,就传递给下一个中间件。
复杂的路由需要安装 koa-router:
由于 koa 使用 generator 作为中间件,所以 myRouter.routes() 返回的是一个 generator,并等同于
myRouter.middleware
:koa-router 提供了一系列于 HTTP 动词对应的方法:
del
是delete
的别名:这些动词方法可以接受两个参数,第一个是路径模式,第二个是对应的控制器方法(中间件),定义用户请求该路径时服务器行为。
注意,路径匹配的时候,不会把查询字符串考虑在内。比如,/index?param=xyz 匹配路径 /index。
关于 koa-router 的更多细节,且听下回分解。
相关阅读
Koa框架
koa的中间件机制
The text was updated successfully, but these errors were encountered: