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函数自动执行。