-
Notifications
You must be signed in to change notification settings - Fork 3
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 #19
Comments
装一下 github-linker 就可以直接点进去 |
koa-compose 和 koa middleware 流程分析 var compose = require('koa-compose'); 使用 var gen = compose(middlewares) => 返回 generator function compose 代码 function compose(middleware){
return function *(next){
if (!next) next = noop();
var i = middleware.length;
while (i--) {
next = middleware[i].call(this, next);
}
yield *next;
}
} 后用 fn = co.wrap(gen),在app.callback里调用fn co(function*(next){
// 直接一个next不好理解,可以看 2.3.0 tag
// https://github.com/koajs/compose/blob/2.3.0/index.js#L25
var i = middleware.length;
var prev = next || noop();
var curr;
while (i--) {
curr = middleware[i];
prev = curr.call(this, prev);
}
yield *next;
}) 就是 从后往前把各个 middleware调用一些,由于是 GeneratorFunction,不会立即执行,而是返回generator,放在prev参数中传入前面一个,作为next...最后的 prev 就是 koa里面最前面的Respond middleware的 gen; 例如代码 var koa = require('koa');
var app = koa();
app.use(middleware1);
function* middleware1(next) {
this.echo("step1");
yield next;
this.echo('step4');
}
app.use(middleware2);
function* middleware2(next) {
this.echo('step2');
yield next;
this.echo('step3')
}
app.context.echo = function(text) {
if (typeof this.body === 'undefined') {
this.body = '';
}
this.body += text + '\n';
}
app.listen(3000, function() {
console.log("server listening at http://localhost:3000");
}); 这个输出顺序是 1234
|
|
yield* https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/yield* 在koa库中大量用到 ... 可以yield* 另一个generator , 或 可 iterable 值,如 Array/String ... 在koa-* 库中,使用 yield* next , 比yield next 的区别是
yield* 值 值可以是任何值, 带输出值的, 例如 string, array, object |
koa 错误处理
context.throwcontext.throw(status,message,props) 其实就是 throw 一个 ServerInternalError 实例, 并且有 status 属性,然后 有err.expose 属性,表示这个错误信息可以被发送到client端. 见 https://github.com/koajs/koa/blob/master/lib%2Fcontext.js#L99 use
if( env != production ){
app.on('error',app.onerror); // 调用默认的 console.error(error);
app.on('error',function(err,ctx){
err.expose = true; // 可expose, 但是 ctx.onerror 的输出只是 err.message
});
} else {
app.on('error',function(err,ctx){
// 自己输出自定义页面 或者使用默认的 ctx.onerror 输出一段默认的原因
// 如果是未找到文件, 输出404
// ENOENT support
if ('ENOENT' == err.code) err.status = 404;
});
} koa-onerrorconst onerror = require('koa-onerror')
const app = new Koa
onerror(app) patch 的是 |
koa-routervar router = require('koa-router')();
...
app.use(router.routes());
app.use(router.allowedMethods());
... 这个换tj来写,肯定是 像express那种 var proto = {};
function Router(){
var router = function * (){
// dispatch here ...
}
router.__proto__ = proto;
return router;
}
proto.get / post / put / delete blabla ... 这样可以app.use(router) 就够了, koa-router 里的 router.routes 其实也就是 dispatch request |
koa-send 发送文件 send(context,path,{
root: <root>
})
// 简单的 createReadStream koa-static 静态中间件 var serve = require('koa-static');
serve(root,options) -> send(context,context.path, {
root: root
}) |
koa 中 context request 中关于path的部分
累觉不爱了! |
默认的 respond默认的respond middleware做了哪些事 https://github.com/koajs/koa/blob/master/lib%2Fapplication.js#L180 总的: 根据 ctx.body & ctx.status 来用 ctx.res node原生的response 来响应 |
faviconvar favicon = require koa-favicon |
trekjs/router 实现分析Node
Router
add |
koa v2 alpha 1middlewareuse() https://github.com/koajs/koa/blob/2.0.0-alpha.1/lib/application.js#L94
koa-composehttps://github.com/koajs/compose/blob/3.0.0/index.js#L31 return function (context, next) {
...
return dispatch(0)
function dispatch(i) {
...
const fn = middleware[i] || next
try {
return Promise.resolve(fn(context, function next() {
return dispatch(i + 1)
}))
} catch(err) {
return Promise.reject(err);
}
}
} 留下基本骨架看看, so middleware = function(ctx, next){
return new Promise...
next = function(){
return dispatch(下一个middleware) -> Promise.resolve( fn( ctx, next ))
}
next() 返回的是下一个middleware执行的Promise
} |
bodyparserkoa-bodyparser -> co-body -> raw-body 包 multipart/form-data
|
application.js 库
on-finished
判断res OutgoingMessage , req IncomingMessage, 的 状态(通过属性,socket状态)
The text was updated successfully, but these errors were encountered: