1. Application.js 暴露listen和use
2. context.js 上下文ctx,实现代理,ctx.response.status --->ctx.status
3. Request.js response.js 是对原生res,req的操作
4. Koa-compose 组合中间件,递归next
function compose(middleware) {
// 传入对象 context 返回Promise
return function (context, next) {
// last called middleware #
let index = -1
return dispatch(0)
function dispatch(i) {
index = i
let fn = middleware[i]
if (i === middleware.length) fn = next
if (!fn) return Promise.resolve()
try {
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
} catch (err) {
return Promise.reject(err)
}
}
}
}
5. koa洋葱模型怎么实现的
app.use() 把中间件函数存储在middleware
数组中,最终会调用koa-compose
导出的函数compose
返回一个promise
,中间函数的第一个参数ctx
是包含响应和请求的一个对象,会不断传递给下一个中间件。next
是一个函数,返回的是一个promise
。
// 看这段
const [fn1, fn2, fn3] = this.middleware;
const fnMiddleware = function(context){
return Promise.resolve(
fn1(context, function next(){
return Promise.resolve(
fn2(context, function next(){
return Promise.resolve(
fn3(context, function next(){
return Promise.resolve();
})
)
})
)
})
);
};
fnMiddleware(ctx).then(handleResponse).catch(onerror);
6. 如果中间件中的next()
方法报错了怎么办。
中间件链错误会由ctx.onerror
捕获,该函数中会调用this.app.emit('error', err, this)
(因为koa
继承自events模块
,所以有'emit'和on
等方法),可以使用app.on('error', (err) => {})
,或者app.onerror = (err) => {}
进行捕获。
ctx.onerror = function {
this.app.emit('error', err, this);
};
listen(){
const fnMiddleware = compose(this.middleware);
if (!this.listenerCount('error')) this.on('error', this.onerror);
const onerror = err => ctx.onerror(err);
fnMiddleware(ctx).then(handleResponse).catch(onerror);
}
onerror(err) {
// 代码省略
// ...
}
7、co
的原理是怎样的。
答:co
的原理是通过不断调用generator
函数的next
方法来达到自动执行generator
函数的,类似async、await
函数自动执行。