笔记koa

203 阅读1分钟

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