成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

使用Node.js實現一個express框架

開發 前端
本文介紹了如何使用Node.js來實現一個express框架的,一起來看看吧。

 [[336666]]

手寫一個express系列

express的基本用法 

  1. const express = require("express");  
  2. const app = express();  
  3. app.get("/test", (req, res, next) => {  
  4.   console.log("*1");  
  5. //   res.end("2");  
  6.   next();  
  7. });  
  8. app.get("/test", (req, res, next) => {  
  9.   console.log("*2");  
  10.   res.end("2");  
  11. });  
  12. app.listen(8888, (err) => {  
  13.   !err && console.log("監聽成功");  
  14. }); 
  •  當我訪問localhost:8888/test時候,返回了:2,服務端打印了 
  1. *1  
  2. *2 
  •  從上面可以看到什么?
    •  express默認引入調用后返回一個app對象
    •  app.listen 會啟動進程監聽端口
    •  每次收到請求,對應的url和method會觸發相應掛載在app上對應的回調函數
    •  調用 next 方法,會觸發下一個

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

  •  定義屬于我們的express文件入口,這里使用class來實現 
  1. class express {  
  2.  
  3. module.exports = express
  •  需要的原生模塊http,創建進程監聽端口 
  1. const { createServer } = require("http"); 
  •  給 class 定義 listen 方法,監聽端口 
  1. class express {  
  2.   listen(...args) {  
  3.     createServer(cb).listen(...args);  
  4.   }  
  •  這樣就可以通過調用 class 的 listen 去調用 http 模塊的 listen 了,這里的cb我們可以先不管,你要知道每次接受到請求,必然會調用 cb 函數,這個是 createServer 原生模塊幫我們封裝好的

實現接收到請求觸發

  •  實現app.get app.post等方法
    •  目前我們接受到響應,就會觸發 cb 這個回調函數,那我們打印下,看看是什么參數? 
  1. class express {  
  2.   cb() {  
  3.     return (req, res) => {  
  4.       console.log(res, res, "開始行動");  
  5.     };  
  6.   }  
  7.   listen(...args) {  
  8.     createServer(this.cb()).listen(...args);  
  9.   }  
  •  發現此時的 req 和 res 正是我們想要的可讀流和可寫流.
  •  開始編寫 get 和 post 方法
    •  這里注意,有路由是'/'的,這種是不管任何路由都會觸發一次 
  1. constructor() {  
  2.     this.routers = {  
  3.       get: [],  
  4.       post: [],  
  5.     };  
  6.   }  
  7.   get(path, handle) {  
  8.     this.routers.get.push({  
  9.       path,  
  10.       handle,  
  11.     });  
  12.   }  
  13.   post(path, handle) {  
  14.     this.routers.post.push({  
  15.       path,  
  16.       handle,  
  17.     });  
  18.   } 
  •  初始化時候定義 get、post 的數組儲存對應的 path 和 handle.
  •  需要觸發路由回調的時候,首先要找到對應的請求方式下對應的 url 的 handle 方法,然后觸發回調.
  •  如何找到對應請求方式下的 url 對應的 handle 方法? 在接到請求時候就要遍歷一次
    •  這里要考慮匹配多個路由,意味著,我們可能遇到像最開始一樣,有兩個 get 方式的 test 路由 
  1. cb() {  
  2.   return (req, res) => {  
  3.     const method = req.method.toLowerCase();  
  4.     console.log(this.routers[method], ",method");  
  5.     const url = req.url;  
  6.     this.routers[method].forEach((item) => {  
  7.       item.path === url && item.handle(req, res);  
  8.     });  
  9.   };  
  10.  
  11. listen(...args) {  
  12.   createServer(this.cb()).listen(...args);  
  •  上面根據 method 找到對應的數組,遍歷找到請求的路由,觸發回調,此時已經能正常返回數據了 
  1. [ { method: 'get', path: '/test', handle: [Function] } ] ,method 
  •  此時最簡單的express已經完成了,但是我們好像忘了最重要的中間件

完成最重要的中間件功能

  •  首先要知道,express中間件分兩種,一種帶路由的,那就是根據路由決定是否觸發
  •  另外一種就是不帶路由的,像靜態資源這種. 是用戶訪問任何路由都要觸發一次的
  •  那我們需要一個 all 數組儲存這種任意路由都需要匹配觸發的 
  1. constructor() {  
  2.    this.routers = {  
  3.      get: [],  
  4.      post: [],  
  5.      all: [],  
  6.    };  
  7.  } 
  •  之前的直接通過 push 方式是太粗暴.如果用戶需要中間件功能,不傳路由,那就要做特殊處理,這里通過一個中間函數處理下
  •  改造get、post方法,定義handleAddRouter方法 
  1. handleAddRouter(path, handle) {  
  2.    let router = {}; 
  3.     if (typeof path === "string") {  
  4.      router = {  
  5.        path,  
  6.        handle,  
  7.      };  
  8.    } else {  
  9.      router = {  
  10.        path: "/",  
  11.        handle: path, 
  12.      };  
  13.    }  
  14.    return router;  
  15.  }  
  16.  get(path, handle) {  
  17.    const router = this.handleAddRouter(path, handle);  
  18.    this.routers.get.push(router);  
  19.  }  
  20.  post(path, handle) {  
  21.    const router = this.handleAddRouter(path, handle);  
  22.    this.routers.post.push(router); 
  23.   }  
  24.  use(path, handle) {  
  25.    const router = this.handleAddRouter(path, handle);  
  26.    this.routers.all.push(router);  
  27.  } 
  •  每次添加之前,先觸發一次handleAddRouter,如果是 path 為空的中間件,直接傳入函數的,那么 path 幫它設置成'/'
  •  我們還遺留了一個點,next的實現,因為我們現在加了all這個數組后,意味著可能有多個中間件,那么可能一次請求打過來,就要觸發多個路由

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

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

實現next

  •  思路:
    •  首先要找到所有匹配的路由
    •  然后逐個執行(看 next 的調用)
  •  定義search方法,找到所有匹配的路由 
  1. search(method, url) {  
  2.     const matchedList = [];  
  3.     [...this.routers[method], ...this.routers.all].forEach((item) => {  
  4.       item.path === url && matchedList.push(item.handle);  
  5.     });  
  6.     return matchedList;  
  7.   }  
  8.   cb() {  
  9.     return (req, res) => {  
  10.       const method = req.method.toLowerCase();  
  11.       const url = req.url;  
  12.       const matchedList = this.search(method, url);  
  13.     };  
  14.   } 
  •  matchedList就是我們想要找到的所有路由
  •  為了完成next,我們要將req ,res , matchedList存入閉包中,定義handle方法 
  1. handle(req, res, matchedList) {  
  2.    const next = () => {  
  3.      const midlleware = matchedList.shift();  
  4.      if (midlleware) {  
  5.        midlleware(req, res, next);  
  6.      }  
  7.    };  
  8.    next();  
  9.  }  
  10.  cb() {  
  11.    return (req, res) => {  
  12.      const method = req.method.toLowerCase();  
  13.      const url = req.url;  
  14.      const matchedList = this.search(method, url);  
  15.      this.handle(req, res, matchedList);  
  16.    };  
  17.  } 
  •  這樣我們就完成了next方法,只要手動調用 next 就會調用下一個匹配到的路由回調函數
  •  不到一百行代碼,就完成了這個簡單的express框架

寫在最后

  •  只要你根據我這些文章去認真自己實現一次,一年內拿個 P6 應該沒什么問題
  •  大道至簡,希望你能通過這些文章真的學到框架的原理,進而自己能寫出一些框架,走向更高的層級
  •  我是Peter,曾經 20 萬人超級群桌面軟件的架構師,現在就職于明源云,擔任分公司前端負責人,目前深圳這邊需要招聘兩位中高級前端,3D數據可視化方向,期待你的到來
  •  如果感覺本文對你有幫助,別忘了點個在看和關注. 我們的技術團隊也會不斷產出原創文章, 一起見證各位的成長 

 

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2011-10-25 09:28:30

Node.js

2022-10-18 18:43:40

Node.js低代碼

2017-04-24 08:31:26

Node.jsExpress.jsHTTP

2019-04-15 11:00:46

框架Node.JS開發

2020-05-29 15:33:28

Node.js框架JavaScript

2023-05-12 07:31:58

NuxtVue.js

2020-07-15 08:06:04

Node.js框架開發

2021-07-16 04:56:03

NodejsAddon

2014-07-11 14:16:15

AbsurdJSExpress

2020-10-29 16:00:03

Node.jsweb前端

2021-08-20 16:05:28

JavaScript node.js 應用安全

2019-08-29 10:58:02

Web 開發框架

2022-05-23 10:26:50

Node.jsJavaScrip

2011-06-17 10:29:04

Nodejavascript

2022-06-05 13:52:32

Node.jsDNS 的原理DNS 服務器

2020-02-25 12:27:59

Node.jsWeb開發前端

2014-04-10 09:43:00

Node.jsTwilio

2012-01-10 10:04:43

Node.js

2022-08-28 16:30:34

Node.jsDocker指令

2014-10-30 10:28:55

Node.js
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲精品一区二区 | 黄色片在线看 | 欧美综合在线视频 | 日韩久草| 国产精品美女久久久久久免费 | 在线国产一区二区 | 亚洲精品自在在线观看 | 日日夜夜天天综合 | 国产高清精品一区 | 久久国产精品亚洲 | aaa国产大片| 九九久久国产精品 | 99综合网 | 国产乱xxav | 亚洲视频中文字幕 | 免费国产一区二区 | 免费a网 | 日本在线综合 | 欧美电影免费观看 | 天天澡天天操 | 亚洲成人www | 天天干干 | 国产精品美女久久久久久免费 | 美国a级毛片免费视频 | 国产精品一区二区三 | 日韩精品在线观看免费 | 国产中的精品av涩差av | 久久久久国产一区二区三区四区 | 亚洲成人第一页 | aaaa一级毛片 | 日本久久久影视 | 亚洲精品福利视频 | 日韩精品一区二区三区视频播放 | 国产精品久久久久久久久久久久久久 | 日韩精品一区在线观看 | 国产午夜精品一区二区三区四区 | 成人免费xxxxx在线视频 | 欧洲一级毛片 | 伊人久久麻豆 | av免费观看在线 | 久久久久久91 |