国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

詳解KOA2如何手寫中間件(裝飾器模式)

2024-05-06 15:28:50
字體:
來源:轉載
供稿:網友

前言

Koa 2.x 版本是當下最流行的 NodeJS 框架, Koa 2.0 的源碼特別精簡,不像 Express 封裝的功能那么多,所以大部分的功能都是由 Koa 開發團隊(同 Express 是一家出品)和社區貢獻者針對 Koa 對 NodeJS 的封裝特性實現的中間件來提供的,用法非常簡單,就是引入中間件,并調用 Koa 的 use 方法使用在對應的位置,這樣就可以通過在內部操作 ctx 實現一些功能,我們接下來就討論常用中間件的實現原理以及我們應該如何開發一個 Koa 中間件供自己和別人使用。

Koa 的洋蔥模型介紹

我們本次不對洋蔥模型的實現原理進行過多的刨析,主要根據 API 的使用方式及洋蔥模型分析中間件是如何工作的。

洋蔥模型特點

// 引入 Koaconst Koa = require("koa");// 創建服務const app = new Koa();app.use(async (ctx, next) => {  console.log(1);  await next();  console.log(2);});app.use(async (ctx, next) => {  console.log(3);  await next();  console.log(4);});app.use(async (ctx, next) => {  console.log(5);  await next();  console.log(6);});// 監聽服務app.listen(3000);// 1// 3// 5// 6// 4// 2

我們知道 Koa 的 use 方法是支持異步的,所以為了保證正常的按照洋蔥模型的執行順序執行代碼,需要在調用 next 的時候讓代碼等待,等待異步結束后再繼續向下執行,所以我們在 Koa 中都是建議使用 async/await 的,引入的中間件都是在 use 方法中調用,由此我們可以分析出每一個 Koa 的中間件都是返回一個 async 函數的。

koa-bodyparser 中間件模擬

想要分析 koa-bodyparser 的原理首先需要知道用法和作用, koa-bodyparser 中間件是將我們的 post 請求和表單提交的查詢字符串轉換成對象,并掛在 ctx.request.body 上,方便我們在其他中間件或接口處取值,使用前需提前安裝。

npm install koa koa-bodyparser

koa-bodyparser 具體用法如下:

koa-bodyparser 的用法

const Koa = require("koa");const bodyParser = require("koa-bodyparser");const app = new Koa();// 使用中間件app.use(bodyParser());app.use(async (ctx, next) => {  if (ctx.path === "/" && ctx.method === "POST") {    // 使用中間件后 ctx.request.body 屬性自動加上了 post 請求的數據    console.log(ctx.request.body);  }});app.listen(3000);

根據用法我們可以看出 koa-bodyparser 中間件引入的其實是一個函數,我們把它放在了 use 中執行,根據 Koa 的特點,我們推斷出 koa-bodyparser 的函數執行后應該給我們返回了一個 async 函數,下面是我們模擬實現的代碼。

文件:my-koa-bodyparser.js

const querystring = require("querystring");module.exports = function bodyParser() {  return async (ctx, next) => {    await new Promise((resolve, reject) => {      // 存儲數據的數組      let dataArr = [];      // 接收數據      ctx.req.on("data", data => dataArr.push(data));      // 整合數據并使用 Promise 成功      ctx.req.on("end", () => {        // 獲取請求數據的類型 json 或表單        let contentType = ctx.get("Content-Type");        // 獲取數據 Buffer 格式        let data = Buffer.concat(dataArr).toString();        if (contentType === "application/x-www-form-urlencoded") {          // 如果是表單提交,則將查詢字符串轉換成對象賦值給 ctx.request.body          ctx.request.body = querystring.parse(data);        } else if (contentType === "applaction/json") {          // 如果是 json,則將字符串格式的對象轉換成對象賦值給 ctx.request.body          ctx.request.body = JSON.parse(data);        }        // 執行成功的回調        resolve();      });    });    // 繼續向下執行    await next();  };};            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 苏尼特右旗| 宁蒗| 故城县| 舒兰市| 平和县| 大理市| 沙田区| 新兴县| 赣州市| 佛坪县| 奉化市| 鄢陵县| 巩留县| 大庆市| 乐平市| 儋州市| 阳春市| 合山市| 龙陵县| 上林县| 喀喇沁旗| 翁牛特旗| 大兴区| 桐柏县| 简阳市| 射阳县| 桂林市| 清水县| 平顺县| 开平市| 安顺市| 松江区| 渑池县| 绥芬河市| 武鸣县| 台州市| 汝阳县| 平罗县| 睢宁县| 昭通市| 班戈县|