Koa v2.x 中文文檔 使用指南

指南

此係列文章的應用示例已發佈於 GitHub: koa-docs-Zh-CN. 能夠 Fork 幫助改進或 Star 關注更新. 歡迎 Star.前端

本指南涵蓋的 Koa 主題不與 API 直接相關,例如編寫中間件的最佳作法和應用程序結構建議。在這些例子中,咱們使用 async 函數做爲中間件 - 您也可使用 commonFunction 或generatorFunction,這將些所不一樣。node

編寫中間件

Koa 中間件是簡單的函數,它返回一個帶有簽名 (ctx, next) 的MiddlewareFunction。當中間件運行時,它必須手動調用 next() 來運行 「下游」 中間件。git

例如,若是你想要跟蹤經過添加 X-Response-Time 頭字段經過 Koa 傳播請求須要多長時間,則中間件將以下所示:github

async function responseTime(ctx, next) {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
}

app.use(responseTime);

若是您是前端開發人員,您能夠將 next(); 以前的任意代碼視爲「捕獲」階段,這個簡易的 gif 說明了 async 函數如何使咱們可以恰當地利用堆棧流來實現請求和響應流:promise

koa middleware

  1. 建立一個跟蹤響應時間的日期
  2. 等待下一個中間件的控制
  3. 建立另外一個日期跟蹤持續時間
  4. 等待下一個中間件的控制
  5. 將響應主體設置爲「Hello World」
  6. 計算持續時間
  7. 輸出日誌行
  8. 計算響應時間
  9. 設置 X-Response-Time 頭字段
  10. 交給 Koa 處理響應

接下來,咱們將介紹建立 Koa 中間件的最佳作法。markdown

中間件最佳實踐

本節介紹中間件創做最佳實踐,例如中間件接受參數,命名中間件進行調試等等。app

中間件參數

當建立公共中間件時,將中間件包裝在接受參數的函數中,遵循這個約定是有用的,容許用戶擴展功能。即便您的中間件 接受任何參數,這仍然是保持統一的好方法。dom

這裏咱們設計的 logger 中間件接受一個 format 自定義字符串,並返回中間件自己:koa

function logger(format) {
  format = format || ':method ":url"';

  return async function (ctx, next) {
    const str = format
      .replace(':method', ctx.method)
      .replace(':url', ctx.url);

    console.log(str);

    await next();
  };
}

app.use(logger());
app.use(logger(':method :url'));

命名中間件

命名中間件是可選的,可是在調試中分配名稱頗有用。異步

function logger(format) {
  return async function logger(ctx, next) {

  };
}

將多箇中間件與 koa-compose 相結合

有時您想要將多箇中間件 「組合」 成一個單一的中間件,便於重用或導出。你可使用 koa-compose

const compose = require('koa-compose');

async function random(ctx, next) {
  if ('/random' == ctx.path) {
    ctx.body = Math.floor(Math.random() * 10);
  } else {
    await next();
  }
};

async function backwards(ctx, next) {
  if ('/backwards' == ctx.path) {
    ctx.body = 'sdrawkcab';
  } else {
    await next();
  }
}

async function pi(ctx, next) {
  if ('/pi' == ctx.path) {
    ctx.body = String(Math.PI);
  } else {
    await next();
  }
}

const all = compose([random, backwards, pi]);

app.use(all);

響應中間件

中間件決定響應請求,並但願繞過下游中間件能夠簡單地省略 next()。一般這將在路由中間件中,但這也能夠任意執行。例如,如下內容將以 「two」 進行響應,可是全部三個都將被執行,從而使下游的 「three」 中間件有機會操縱響應。

app.use(async function (ctx, next) {
  console.log('>> one');
  await next();
  console.log('<< one');
});

app.use(async function (ctx, next) {
  console.log('>> two');
  ctx.body = 'two';
  await next();
  console.log('<< two');
});

app.use(async function (ctx, next) {
  console.log('>> three');
  await next();
  console.log('<< three');
});

如下配置在第二個中間件中省略了next(),而且仍然會以 「two」 進行響應,然而,第三個(以及任何其餘下游中間件)將被忽略:

app.use(async function (ctx, next) {
  console.log('>> one');
  await next();
  console.log('<< one');
});

app.use(async function (ctx, next) {
  console.log('>> two');
  ctx.body = 'two';
  console.log('<< two');
});

app.use(async function (ctx, next) {
  console.log('>> three');
  await next();
  console.log('<< three');
});

當最遠的下游中間件執行 next(); 時,它其實是一個 noop 函數,容許中間件在堆棧中的任意位置正確組合。

異步操做

Async 方法和 promise 來自 Koa 的底層,可讓你編寫非阻塞序列代碼。例如,這個中間件從 ./docs 讀取文件名,而後在將給 body 指定合併結果以前並行讀取每一個 markdown 文件的內容。

const fs = require('fs-promise');

app.use(async function (ctx, next) {
  const paths = await fs.readdir('docs');
  const files = await Promise.all(paths.map(path => fs.readFile(`docs/${path}`, 'utf8')));

  ctx.type = 'markdown';
  ctx.body = files.join('');
});

調試 Koa

Koa 以及許多構建庫,支持來自 debugDEBUG 環境變量,它提供簡單的條件記錄。

例如,要查看全部 koa 特定的調試信息,只需經過 DEBUG=koa*,而且在啓動時,您將看到所使用的中間件的列表。

$ DEBUG=koa* node --harmony examples/simple
  koa:application use responseTime +0ms
  koa:application use logger +4ms
  koa:application use contentLength +0ms
  koa:application use notfound +0ms
  koa:application use response +0ms
  koa:application listen +0ms

因爲 JavaScript 在運行時沒有定義函數名,你也能夠將中間件的名稱設置爲 ._name。當你沒法控制中間件的名稱時,這頗有用。例如:

const path = require('path');
const serve = require('koa-static');

const publicFiles = serve(path.join(__dirname, 'public'));
publicFiles._name = 'static /public';

app.use(publicFiles);

如今,在調試時不僅會看到 「serve」,你也會看到:
Now, instead of just seeing "serve" when debugging, you will see:

koa:application use static /public +0ms

若是這篇文章對您有幫助, 感謝 下方點贊 或 Star GitHub: koa-docs-Zh-CN 支持, 謝謝.

相關文章
相關標籤/搜索