koa源代码

koa不愧为小而美,主要代码很少。
简单来说,
1,koa封装了node的http.createServer((req,res)=>{})的
入参req,res到ctx(一个自定义对象)的req,res属性中,
并且额外提供了ctx.request,ctx.request提供一些快捷的操作。
const app = Koa()
app.use(middlewareFn)
2.方法use函数接收参数fn,放入中间件middleware[]数组里面。
  handleRequest(ctx, fnMiddleware) {
    const res = ctx.res;
    const handleResponse = () => respond(ctx);
    return fnMiddleware(ctx).then(handleResponse).catch(onerror);
  }
fnMiddleware即处理过的middleware数组:
function compose (middleware) {
  return function (context, next) {
    // last called middleware #
    let index = -1
    return dispatch(0)
    function dispatch (i) {
      if (i <= index) return Promise.reject(new Error('next() called multiple times'))
      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)
      }
    }
  }
}

递归的展开就是洋葱模型了:

const [fn1, fn2, fn3] = this.middleware;
const fnMiddleware = function(ctx){
    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);

ctx:

createContext(req, res) {
    const context = Object.create(this.context);
    const request = context.request = Object.create(this.request);
    const response = context.response = Object.create(this.response);
    context.app = request.app = response.app = this;
    context.req = request.req = response.req = req;
    context.res = request.res = response.res = res;
    request.ctx = response.ctx = context;
    request.response = response;
    response.request = request;
    context.originalUrl = request.originalUrl = req.url;
    context.state = {};
    return context;
  }

 

上一篇:1012 数字分类 (20 分)


下一篇:int 打印成32位