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

10分鐘理解Node.js koa源碼架構(gòu)設(shè)計

開發(fā) 架構(gòu)
koa 發(fā)布已經(jīng)快 6 年的時間,作為繼 express 之后 node 服務(wù)框架最大的黑馬,有很多的設(shè)計思想值得我們學(xué)習(xí),本文從簡到繁逐步介紹 koa,同時適合新老手閱讀。

 [[271573]]

koa 發(fā)布已經(jīng)快 6 年的時間,作為繼 express 之后 node 服務(wù)框架最大的黑馬,有很多的設(shè)計思想值得我們學(xué)習(xí),本文從簡到繁逐步介紹 koa,同時適合新老手閱讀。

介紹

這里引用中文官方網(wǎng)站的原文

Koa 是一個新的 web 框架,由 Express 幕后的原班人馬打造, 致力于成為 web 應(yīng)用和 API 開發(fā)領(lǐng)域中的一個更小、更富有表現(xiàn)力、更健壯的基石。 通過利用 async 函數(shù),Koa 幫你丟棄回調(diào)函數(shù),并有力地增強錯誤處理。 Koa 并沒有捆綁任何中間件, 而是提供了一套優(yōu)雅的方法,幫助您快速而愉快地編寫服務(wù)端應(yīng)用程序。 

既然是 web 框架大家一定不陌生,通過啟動一個 node http server,監(jiān)聽一個端口,進而我們就可以通過類似 localhost:3000 在本地訪問我們的服務(wù)了,這個服務(wù)可以是 web 網(wǎng)站,可以是 restful 接口,也可以是靜態(tài)文件服務(wù)等等。

Hello Word

任何語言、框架都存在 Hello Word 示例,來表達其最簡單的入門 Demo,代碼如下:

此時訪問瀏覽器 localhost:3000,我們會看到打印出了 Hello Word,此時一個基于 koa 的服務(wù)就啟動完成了。

上下文

理解 koa 第一步,搞清楚上下文的作用

例如:微信群里面有人說外面下雪了,你跑到窗邊看到的卻是晴空萬里,這時你才意識到同樣是 10 月份,他在寒冷的北方,你在酷暑的南方。

類似的,一次請求會包含用戶的登錄狀態(tài),或者一些Token之類的信息,這些信息就是上下文的一部分,用于確定一次的請求環(huán)境。

Koa 的 Context 把 node 的 request, response 對象封裝進一個單獨對象, 并提供許多開發(fā) web 應(yīng)用和 APIs 有用的方法. 那些在 HTTP server 開發(fā)中使用非常頻繁操作, 直接在 Koa 里實現(xiàn), 而不是放在更高層次的框架, 這樣中間件就不需要重復(fù)實現(xiàn)這些通用的功能。

中間件

先來看一個官方的例子:

簡單解釋下,代碼起始初始化一個 koa 實例,下面分別通過 use 方法載入了三個中間件方法,執(zhí)行順序:

  1.  進入第一個中間件
  2.  next() 跳到下一個中間件
  3.  new Data() 記錄當(dāng)前時間
  4.  next() 跳到下一個中間件
  5.  將 ctx.body 賦值
  6.  回到上一個中間件再次記錄當(dāng)前時間并計算時間差存到 http header 中
  7.  回到上一個中間件將 header 中的 X-Response-time 打印出來

這里的執(zhí)行順序延伸出了十分經(jīng)典的洋蔥模型:

在一次請求的過程中會往返經(jīng)過同一中間件兩次,允許我們處理不同請求階段的邏輯。

源碼解析 

上面分別介紹了 koa 里面兩個最重要的概念,下面我們分析下 koa 內(nèi)部是如何運作的,所謂的洋蔥模型是如何建立的。

koa 源碼的 lib 目錄十分簡單。

  1. lib  
  2.   |- application.js  
  3.   |- context.js  
  4.   |- request.js  
  5.   |- response.js 

Application 類初始化

入口文件是 application.js,我們先從這里入手。

Application 是一個 class,這個類繼承了 node 的 Events 這里不詳細展開,在 constructor 中初始化了以下內(nèi)容:

  •  proxy 代理默認不開啟
  •  middleware 中間件是個空數(shù)組,這里重點注意下
  •  env 根據(jù)環(huán)境變量 NODE_ENV 來判斷
  •  context、request、response 分別通過 Object.create 方法將 lib 目錄下對應(yīng)的文件導(dǎo)入到 this 當(dāng)前上下文,且不污染引入對象

use 方法

按照正常的編碼順序,在初始化完 koa 實例后(即 const app = new Koa()),我們需要調(diào)用 app.use() 去掛載我們的中間件,那么我們看下 use 方法做了什么。

判斷中間件為 function,判斷中間件是否為 generator function 類型,只是簡單的將中間件函數(shù) push 到了 middleware 數(shù)組中。

此時心中有沒有大寫的 WHAT?

其實就是這么直白,沒什么復(fù)雜邏輯,后面也許大家都猜到了,循環(huán)調(diào)用 middleware 中的方法去執(zhí)行,此處尚未表明洋蔥模型是怎么來的,我們先不展開,繼續(xù)按代碼順序執(zhí)行。

listen 方法

按照正常的編碼順序,在 use 完我們的中間件之后就是 app.listen(3000)

一起看下這個 listen 干了什么。 

這里的 http.createServer 就是 node 原生啟動 http 服務(wù)的方法,這里稍微擴展下基礎(chǔ)知識,此方法接受兩個參數(shù)。

  •  options[IncomingMessage, ServerResponse] 這里從 node 版本 v9.6.0, v8.12.0 后才支持,這里不贅述。
  •  requestListener 此參數(shù)為 function 類型,每次請求會傳入 req, res 兩個參數(shù)

不難理解這里的 this.callback() 方法一定是返回了一個函數(shù),并且接收兩個參數(shù) (req, res),下面看下源碼:

這個 callback 中的信息量有點大,代碼本身并不難理解,注釋也有說明,從這里展開從上到下分別解釋。

compose 方法

這里的 compose 方法主要負責(zé)生成洋蔥模型,通過 koa-compose 包實現(xiàn),源碼如下:

從注釋看得出大致邏輯,這里的巧妙之處在于 fn(context, dispatch.bind(null, i + 1))。

這個 dispatch.bind(null, i + 1) 就是我們通常寫中間件的第二個參數(shù) next。

我們執(zhí)行這個 next() 方法實際上得到的是下一個中間件的執(zhí)行。

也就不難理解為什么我們 await next() 的時候等待的是后面所有中間件串聯(lián)執(zhí)行后了,回頭再看下上文中間件部分的執(zhí)行順序就豁然開朗了。

createContext 方法

callback 中的展開解釋,看下 const ctx = this.createContext(req, res) 做了什么。

這里主要是將 req, res 及 this.request, this.response 都掛載到了 context 上,并通過賦值理清了循環(huán)引用層級關(guān)系,為使用者提供方便。

handleRequest 方法

還是 callback 中的展開解釋,看下 this.handleRequest(ctx, fn) 這部分做了什么。

分別拿到 ctx 和 compose 生成的洋蔥模型,開始逐一消費中間件。

context.js 文件

上面理清了整體框架,下面看下 context.js 內(nèi)部的細節(jié),在文件結(jié)尾有兩大段的代理。

這里可以看到所有的 req 及 res 的方法集合,那么哪些方法可讀,哪些可寫,哪些既可讀又可寫,哪些方法不允許修改。

這就是 delegates 這個庫做的事情。

delegates 內(nèi)部利用了,__defineGetter__ 和 __defineSetter__ 方法控制讀寫,當(dāng)然我們可以從中學(xué)習(xí)思想,也不能盲從。

這兩個 api 去 MDN 上搜索會給出相同的警告信息

This feature is deprecated in favor of defining setters using the object initializer syntax or the Object.defineProperty() API。

其實還是建議我們使用 vue 的代理方式 Object.defineProperty(),不過這個庫有四年沒更新了依然穩(wěn)定運行著,還是深受 koa 開發(fā)者認可的。

其它

request.js 和 response.js 文件沒什么可以講,就是具體的工具方法實現(xiàn),方便開發(fā)人員調(diào)用,感興趣可以自行閱讀源碼。

應(yīng)用

智聯(lián)前端架構(gòu)整體的 node 服務(wù)都基于 koa 實現(xiàn),包括我們的 vue 服務(wù)端渲染和 node restful api 等等。

我們選擇 koa 的原因是其本身輕巧,可擴展性良好,支持 async、await 的異步,徹底擺脫了回調(diào)地獄。

市面上也有成熟基于 koa2 的企業(yè)級解決方案,如 eggjs 和 thinkjs。

總結(jié)

揭開 koa 的神秘面紗,讓開發(fā)者關(guān)注業(yè)務(wù)邏輯同時也關(guān)注下框架本身,有利于問題排查和編寫擴展,與此同時可以學(xué)習(xí) express、hapi 等同類型框架的思想,結(jié)合現(xiàn)有企業(yè)級解決方案,選一款適合你的框架,總之框架不論好壞,只論場景。

 

責(zé)任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2013-11-01 09:34:56

Node.js技術(shù)

2019-05-22 09:28:21

TCPUDP端口號

2021-09-12 22:22:45

Mock數(shù)據(jù)服務(wù)

2019-12-17 11:40:44

Node.js模塊前端

2019-11-11 21:24:42

HadoopHbase分布式

2021-08-05 05:46:06

Node.jsInspector工具

2024-01-05 08:49:15

Node.js異步編程

2021-05-27 09:00:00

Node.js開發(fā)線程

2021-10-16 05:00:32

.js Buffer模塊

2015-03-12 17:01:33

MySQLMySQL亂碼編碼轉(zhuǎn)換

2021-07-15 06:43:11

Bash調(diào)試腳本

2021-09-01 13:32:48

Node.jsAPI POSIX

2020-03-17 13:24:04

微服務(wù)架構(gòu)數(shù)據(jù)

2024-09-18 08:21:24

JavaScriptTypeScriptprototype

2013-09-13 14:08:01

2020-11-10 16:01:25

程序員設(shè)計模式技術(shù)

2018-08-23 16:18:59

2021-08-12 01:00:29

NodejsAsync

2021-08-26 13:57:56

Node.jsEncodingBuffer

2017-08-16 10:36:10

JavaScriptNode.js事件驅(qū)動
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久久出精品| 成人黄色三级毛片 | 亚洲精品99| 偷拍亚洲色图 | 成人毛片网站 | 国产成人精品一区二区三区视频 | 免费av电影网站 | 在线看av网址| 毛片视频免费观看 | 欧美精品91 | 999热视频| 欧美三区视频 | 美女视频h | 日韩一区二区视频 | 亚洲精品电影网在线观看 | 欧美精品在欧美一区二区少妇 | 国产专区视频 | 欧美一区二区三区久久精品 | 精品国产乱码久久久久久牛牛 | 精品视频一区二区三区在线观看 | 美女国产一区 | 91成人精品视频 | 午夜大片| 亚洲综合在线视频 | 欧美成人精品激情在线观看 | 精品日韩一区 | 国产精品久久久爽爽爽麻豆色哟哟 | 国内自拍视频在线观看 | 在线视频日韩 | 欧美性成人 | 国产三区精品 | 国产精品久久久久久久久免费高清 | 国产精品爱久久久久久久 | 国产伦精品一区二区三区高清 | 亚洲高清视频一区二区 | 国产精品久久久久久久久 | 自拍第1页| 国产精品视频久久 | 午夜网站视频 | 黄色成人免费在线观看 | 亚洲一区导航 |