溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Node.js中怎么實現一個express框架

發布時間:2021-07-20 16:31:57 來源:億速云 閱讀:208 作者:Leah 欄目:web開發

本篇文章給大家分享的是有關Node.js中怎么實現一個express框架,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

express的基本用法

const express = require("express");  const app = express();  app.get("/test", (req, res, next) => {    console.log("*1");  //   res.end("2");    next();  });  app.get("/test", (req, res, next) => {    console.log("*2");    res.end("2");  });  app.listen(8888, (err) => {    !err && console.log("監聽成功");  });
  •  當我訪問localhost:8888/test時候,返回了:2,服務端打印了 

*1  *2
  •  從上面可以看到什么?

    •  express默認引入調用后返回一個app對象

    •  app.listen 會啟動進程監聽端口

    •  每次收到請求,對應的url和method會觸發相應掛載在app上對應的回調函數

    •  調用 next 方法,會觸發下一個

一起來實現一個簡單的express框架

  •  定義屬于我們的express文件入口,這里使用class來實現 

class express {  }  module.exports = express;
  •  需要的原生模塊http,創建進程監聽端口 

const { createServer } = require("http");
  •  給 class 定義 listen 方法,監聽端口 

class express {    listen(...args) {      createServer(cb).listen(...args);    }  }
  •  這樣就可以通過調用 class 的 listen 去調用 http 模塊的 listen 了,這里的cb我們可以先不管,你要知道每次接受到請求,必然會調用 cb 函數,這個是 createServer 原生模塊幫我們封裝好的

實現接收到請求觸發

  •  實現app.get app.post等方法

    •  目前我們接受到響應,就會觸發 cb 這個回調函數,那我們打印下,看看是什么參數? 

class express {    cb() {      return (req, res) => {        console.log(res, res, "開始行動");      };    }    listen(...args) {      createServer(this.cb()).listen(...args);    }  }
  •  發現此時的 req 和 res 正是我們想要的可讀流和可寫流.

  •  開始編寫 get 和 post 方法

    •  這里注意,有路由是'/'的,這種是不管任何路由都會觸發一次 

constructor() {      this.routers = {        get: [],        post: [],      };    }    get(path, handle) {      this.routers.get.push({        path,        handle,      });    }    post(path, handle) {      this.routers.post.push({        path,        handle,      });    }
  •  初始化時候定義 get、post 的數組儲存對應的 path 和 handle.

  •  需要觸發路由回調的時候,首先要找到對應的請求方式下對應的 url 的 handle 方法,然后觸發回調.

  •  如何找到對應請求方式下的 url 對應的 handle 方法? 在接到請求時候就要遍歷一次

    •  這里要考慮匹配多個路由,意味著,我們可能遇到像最開始一樣,有兩個 get 方式的 test 路由 

cb() {    return (req, res) => {      const method = req.method.toLowerCase();      console.log(this.routers[method], ",method");      const url = req.url;      this.routers[method].forEach((item) => {        item.path === url && item.handle(req, res);      });    };  }  listen(...args) {    createServer(this.cb()).listen(...args);  }
  •  上面根據 method 找到對應的數組,遍歷找到請求的路由,觸發回調,此時已經能正常返回數據了 

[ { method: 'get', path: '/test', handle: [Function] } ] ,method
  •  此時最簡單的express已經完成了,但是我們好像忘了最重要的中間件

完成最重要的中間件功能

  •  首先要知道,express中間件分兩種,一種帶路由的,那就是根據路由決定是否觸發

  •  另外一種就是不帶路由的,像靜態資源這種. 是用戶訪問任何路由都要觸發一次的

  •  那我們需要一個 all 數組儲存這種任意路由都需要匹配觸發的 

constructor() {     this.routers = {       get: [],       post: [],       all: [],     };   }
  •  之前的直接通過 push 方式是太粗暴.如果用戶需要中間件功能,不傳路由,那就要做特殊處理,這里通過一個中間函數處理下

  •  改造get、post方法,定義handleAddRouter方法 

handleAddRouter(path, handle) {     let router = {};     if (typeof path === "string") {       router = {         path,         handle,       };     } else {       router = {         path: "/",         handle: path,      };     }     return router;   }   get(path, handle) {     const router = this.handleAddRouter(path, handle);     this.routers.get.push(router);   }   post(path, handle) {     const router = this.handleAddRouter(path, handle);     this.routers.post.push(router);   }   use(path, handle) {     const router = this.handleAddRouter(path, handle);     this.routers.all.push(router);   }
  •  每次添加之前,先觸發一次handleAddRouter,如果是 path 為空的中間件,直接傳入函數的,那么 path 幫它設置成'/'

  •  我們還遺留了一個點,next的實現,因為我們現在加了all這個數組后,意味著可能有多個中間件,那么可能一次請求打過來,就要觸發多個路由

這里要注意,promise.then 源碼實現和 express 的 next、以及 koa 的洋蔥圈、redux 的中間件實現,有著一丁點相似,當你能真的領悟前后端框架源碼時候,發現大都相似

  •  閱讀我的文章,足以擊破所有前后端源碼.而且可以手寫出來, 我們只學最核心的,抓重點學習,野蠻生長!

實現next

  •  思路:

    •  首先要找到所有匹配的路由

    •  然后逐個執行(看 next 的調用)

  •  定義search方法,找到所有匹配的路由 

search(method, url) {      const matchedList = [];      [...this.routers[method], ...this.routers.all].forEach((item) => {        item.path === url && matchedList.push(item.handle);      });      return matchedList;    }    cb() {      return (req, res) => {        const method = req.method.toLowerCase();        const url = req.url;        const matchedList = this.search(method, url);      };    }
  •  matchedList就是我們想要找到的所有路由

  •  為了完成next,我們要將req ,res , matchedList存入閉包中,定義handle方法 

handle(req, res, matchedList) {     const next = () => {       const midlleware = matchedList.shift();       if (midlleware) {         midlleware(req, res, next);       }     };     next();   }   cb() {     return (req, res) => {       const method = req.method.toLowerCase();       const url = req.url;       const matchedList = this.search(method, url);       this.handle(req, res, matchedList);     };   }
  •  這樣我們就完成了next方法,只要手動調用 next 就會調用下一個匹配到的路由回調函數

  •  不到一百行代碼,就完成了這個簡單的express框架

以上就是Node.js中怎么實現一個express框架,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女