koa原始碼總結

JuoJuo發表於2018-11-13

記錄一下讓自己有所收穫的兩點

1.context屬性的擴充

  • context
    • req
    • res
    • request
      • req
    • response
      • res

koa在context上直接擴充了原生req、res的屬性,同時也在request、response上擴充了原生req、res的屬性.


同時也給context以及request、response擴充url、heanders等屬性,方便使用。但是寫法比較有趣:

//當訪問的時候,我們定義了get方法,相當於簡寫defineProperty,返回自身的req屬性的url屬性
let request = {
    get url(){
        return this.req.url
    }
}
console.log(context.request.url)
複製程式碼
//response同理,不過我發現只要自定義get、set自己就得哪一個變數暫時的儲存set的值,以便在get的時候返回去
let response = {
  get body(){
    return this._body;
  },
  set body(value){
    this._body = value;
  }
}
response.body = 123;
console.log(context.response.body)
複製程式碼
//context其實也是一樣的,只不過用api的形式定義的get set
let context = { };
function defineGetter(target,property) {
  context.__defineGetter__(property,function () {
    return this[target][property]
  });
}
function defineSetter(target,property) {
  context.__defineSetter__(property,function (value) {
    this[target][property] = value
  })
}

defineGetter('request','path');
defineGetter('response','body');

// ctx.body = ctx.response.body;
defineSetter('response','body')

context.body = 123;
console.log(context.body)
console.log(context.path)
複製程式碼

2.組合中介軟體的執行

app.use(async (ctx, next) => {
  console.log(1);
  await next(); // 呼叫這個函式的時候 就是當前第二個函式不一定執行完了
  console.log(2);
});
app.use(async (ctx, next) => {
  console.log(3);
  await log()
  await next();
  console.log(4);
})
//我們在執行中介軟體函式的時候,把await next給替換成了await () => dispatch(index+1)
//實際上就是await () => Promise.resolve(middlewares[index]())
//或者await () => if(index === middlewares.length) return Promise.resolve();
compose(ctx, middlewares) {
    function dispatch(index) {
      if (index === middlewares.length) return Promise.resolve();
      let fn = middlewares[index]
      return Promise.resolve(fn(ctx, () => dispatch(index + 1)));
    }
    return dispatch(0)
}
複製程式碼

tips: Promise.resolve如果裡面傳的是個promise,會等待裡面的promise成功或者失敗了以後才會執行它自己的then

相關文章