Express核心原理

逐行解析Express核心原理

文章主要以一下三個部分組成

  1. node 創(chuàng)建http服務
  2. express 創(chuàng)建http服務
  3. 自己寫類express并且解析核心原理

1. node創(chuàng)建http 服務

基于node基本的創(chuàng)建服務

//引入node 模塊
const http = require('http')
//創(chuàng)建服務蚕苇,并且實現(xiàn)callback回調(diào)
const server = http.createServer(callback)
const callback = (req,res) =>{
    res.end("Hello xie")
}
//服務監(jiān)聽3000 端口
server.listen(3000)

上面我們用最原始的方式 創(chuàng)建一個服務哩掺,當訪問localhost:3000即可返回相關數(shù)據(jù)

2. 使用express 創(chuàng)建服務

    npm install express --save
    
    const express = require('express')
    const app = express()
    const port = 3000
    
    //路由
    app.get('/', (req, res) => res.send('Hello World!'))
    app.listen(port, () => console.log(`Example app listening on port ${port}!`))

使用express的優(yōu)勢在于其可以使用中間件,這也是其核心,所謂的中間件涩笤,其實也即使一個函數(shù)function

/**
    定義一個中間件,
    暫且忽略next是啥嚼吞,知道next是一個往下傳遞的方法即可
*/
const middle = (req,res,next) =>{
    //do something
    next()
}

app.use(middle)
app.use("/api",middle, (req,res,next)=>{
    //dosomething
    next()
})

app.get(參數(shù)類似use參數(shù))
app.post(參數(shù)類似use參數(shù)){
    res.json({
        name:'xieyusheng'
    })
}
......

那么問題來了盒件,app.use/get/post/res.json以及最至關重要的next是怎么實現(xiàn)的呢?

3.自己寫個Express框架

姑且就叫XExpress

1. 先定義接結構
const http = require('http')
class XExpress{
    
    use () {
    }
    get () {
    }
    post () {
    }
    callback (){
    }
    listen(...argus){
        const server = http.createServer(callback)
        server.listen(...argus)
    }
}
module.exports = () => new Exprerss()

實例化

   const xErpress = './xExpress'
   const server = new xErpress()
   server.listen(3000)
   

ok舱禽,基本服務啟動好了炒刁,那么use/get等怎么處理呢,這里核心原理來了哦誊稚,其實我們只要將所有的中間件函數(shù)放在一個棧中翔始,然后一個一個執(zhí)行處理,那么怎么一個個處理呢里伯? 使用next函數(shù)

    2. 將所有的中間件放在堆棧中
    //new XExpress 實例化一個單量
    constructor(){
        //存放中間件的list
        this.routes = {
            use: [],   // app.use(...)
            get: [],   // app.get(...)
            post: []   // app.post(...)
        }
    }
    //結構化傳遞來的參數(shù)
    register (path) {
      const info = {};
      if(typeof path == "string"){
      info.path = path;
      //將后面的方法以arr的方式城瞎,放入內(nèi)存中,從第二個參數(shù)開始
      info.stack = slice.call(arguments, 1)
    }else{
      info.path = "/" //當use等方法的第一個參數(shù)是否是鏈接
      //從第一個參數(shù)開始疾瓮,轉換為數(shù)組脖镀,存入 stack
      info.stack = slice.call(arguments, 1)
    }

     return info;
     // info={
     //   path:'/',
     //   stack:[
     //     ()=>{};
     //     ()=>{}
     //   ]
     // }
    }
    use(){
     const info = this.register.apply(this, arguments)
     this.routes.all.push(info)
  }
  ....get/post類似

所有的中間件都賦予在routes里面,那么當請求來了狼电,我們匹配下认然,然后一個個的執(zhí)行

callback(req,res) => {
    //定義方法給req
    req.json= () =>{
        // 定義返回格式
        res.setHeader("Contype-type" : "application/json")
        res.end(
            JSON.stringify(data)
         )
    }
    //1.匹配相對的中間件
       const url = req.url
       const method = req.method.toLowerCase()
       //匹配
       const resultList = this.match(method, url)
      
      //一個一個的執(zhí)行中間件函數(shù)
         this.actionNext(req, res, resultList)
        
}

    /**
    根據(jù)url和method匹配相對應的中間件LIST
    */
    match(method, url) {
        let stack = []
          // 獲取 routes
        let curRoutes = []
        curRoutes =[...this.routes.use]
        curRoutes = [...this.routes.use[method]]
        curRoutes.forEach(routeInfo => {
            if (url.indexOf(routeInfo.path) === 0) {
                stack = stack.concat(routeInfo.stack)
            }
        })
        return stack
    }

    actionNext(req, res, stack){
            // 定義next函數(shù)
          const next = () =>{
                const middleware = stack.shift() //取出第一個
                if(middleware) {
                    //將next 函數(shù)傳遞
                    middleware(req,res,next)
                }
       }
       next();
    }

這樣,next函數(shù)傳遞給每個中間函數(shù)了漫萄,這里的next函數(shù)就是下一個要執(zhí)行函數(shù)的包裝體

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市盈匾,隨后出現(xiàn)的幾起案子腾务,更是在濱河造成了極大的恐慌,老刑警劉巖削饵,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件岩瘦,死亡現(xiàn)場離奇詭異,居然都是意外死亡窿撬,警方通過查閱死者的電腦和手機启昧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來劈伴,“玉大人密末,你說我怎么就攤上這事□髓担” “怎么了严里?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長追城。 經(jīng)常有香客問我刹碾,道長,這世上最難降的妖魔是什么座柱? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任迷帜,我火速辦了婚禮物舒,結果婚禮上,老公的妹妹穿的比我還像新娘戏锹。我一直安慰自己冠胯,他們只是感情好,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布景用。 她就那樣靜靜地躺著涵叮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪伞插。 梳的紋絲不亂的頭發(fā)上割粮,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天,我揣著相機與錄音媚污,去河邊找鬼舀瓢。 笑死,一個胖子當著我的面吹牛耗美,可吹牛的內(nèi)容都是我干的京髓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼商架,長吁一口氣:“原來是場噩夢啊……” “哼堰怨!你這毒婦竟也來了?” 一聲冷哼從身側響起蛇摸,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤备图,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后赶袄,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揽涮,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年饿肺,在試婚紗的時候發(fā)現(xiàn)自己被綠了蒋困。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡敬辣,死狀恐怖雪标,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情溉跃,我是刑警寧澤汰聋,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站喊积,受9級特大地震影響烹困,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乾吻,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一髓梅、第九天 我趴在偏房一處隱蔽的房頂上張望拟蜻。 院中可真熱鬧,春花似錦枯饿、人聲如沸酝锅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搔扁。三九已至,卻和暖如春蟋字,著一層夾襖步出監(jiān)牢的瞬間稿蹲,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工鹊奖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留苛聘,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓忠聚,卻偏偏與公主長得像设哗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子两蟀,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 解析Koa2核心原理(手寫KOA框架并解析) 前言:相對于express框架网梢,koa框架只是提供了async/aw...
    謝玉勝閱讀 952評論 0 0
  • Express官網(wǎng)說:Express是基于 Node.js 平臺的 web 開發(fā)框架。這句話包含了兩個部分內(nèi)容赂毯,一...
    喬治yuanbo閱讀 1,374評論 0 2
  • 引用:https://github.com/WangZhechao/expross 1.簡介 這篇文章是分析exp...
    宮若石閱讀 3,082評論 1 8
  • 1. 簡介 這篇文章主要的目的是分析理解express的源碼战虏,網(wǎng)絡上關于源碼的分析已經(jīng)數(shù)不勝數(shù),這篇文章準備另辟蹊...
    沒事造輪子閱讀 1,320評論 0 8
  • node-interview-questions Node是搞后端的徐裸,不應該被被歸為前端遣鼓,更不應該用前端的觀點去理...
    IT楊閱讀 506評論 0 5