您好,登錄后才能下訂單哦!
小編給大家分享一下koa2怎么用,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
介紹
Koa 是一個新的 web 框架,由 Express 幕后的原班人馬打造, 致力于成為 web 應用和 API 開發(fā)領域中的一個更小、更富有表現(xiàn)力、更健壯的基石。 通過利用 async 函數(shù),Koa 幫你丟棄回調(diào)函數(shù),并有力地增強錯誤處理。 Koa 并沒有捆綁任何中間件, 而是提供了一套優(yōu)雅的方法,幫助您快速而愉快地編寫服務端應用程序。
既然是 web 框架大家一定不陌生,通過啟動一個 node http server,監(jiān)聽一個端口,進而我們就可以通過類似 localhost:3000
在本地訪問我們的服務了,這個服務可以是 web 網(wǎng)站,可以是 restful 接口,也可以是靜態(tài)文件服務等等。
Hello Word
任何語言、框架都存在 Hello Word
示例,來表達其最簡單的入門 Demo,代碼如下
此時訪問瀏覽器 localhost:3000
,我們會看到打印出了 Hello Word
,此時一個基于 koa 的服務就啟動完成了。
上下文
理解 koa 第一步,搞清楚上下文的作用
例如:微信群里面有人說外面下雪了,你跑到窗邊看到的卻是晴空萬里,這時你才意識到同樣是 10 月份,他在寒冷的北方,你在酷暑的南方
類似的,一次請求會包含用戶的登錄狀態(tài),或者一些Token之類的信息,這些信息就是上下文的一部分,用于確定一次的請求環(huán)境
Koa 的 Context 把 node 的 request, response 對象封裝進一個單獨對象, 并提供許多開發(fā) web 應用和 APIs 有用的方法. 那些在 HTTP server 開發(fā)中使用非常頻繁操作, 直接在 Koa 里實現(xiàn), 而不是放在更高層次的框架, 這樣中間件就不需要重復實現(xiàn)這些通用的功能。
中間件
先來看一個官方的例子:
簡單解釋下,代碼起始初始化一個 koa 實例,下面分別通過 use 方法載入了三個中間件方法,執(zhí)行順序:
進入第一個中間件next()
跳到下一個中間件new Data()
記錄當前時間next()
跳到下一個中間件將 ctx.body
賦值回到上一個中間件再次記錄當前時間并計算時間差存到 http header
中回到上一個中間件將 header 中的 X-Response-time
打印出來
這里的執(zhí)行順序延伸出了十分經(jīng)典的洋蔥模型
在一次請求的過程中會往返經(jīng)過同一中間件兩次,允許我們處理不同請求階段的邏輯
源碼解析
上面分別介紹了 koa 里面兩個最重要的概念,下面我們分析下 koa 內(nèi)部是如何運作的,所謂的洋蔥模型是如何建立的
koa 源碼的 lib 目錄十分簡單
lib |- application.js |- context.js |- request.js |- 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 目錄下對應的文件導入到 this
當前上下文,且不污染引入對象
use 方法
按照正常的編碼順序,在初始化完 koa 實例后(即 const app = new Koa()
),我們需要調(diào)用 app.use()
去掛載我們的中間件,那么我們看下 use 方法做了什么
判斷中間件為 function,判斷中間件是否為 generator function 類型,只是簡單的將中間件函數(shù) push
到了 middleware
數(shù)組中。
此時心中有沒有大寫的 WHAT?
其實就是這么直白,沒什么復雜邏輯,后面也許大家都猜到了,循環(huán)調(diào)用 middleware
中的方法去執(zhí)行,此處尚未表明洋蔥模型是怎么來的,我們先不展開,繼續(xù)按代碼順序執(zhí)行。
listen 方法
按照正常的編碼順序,在 use
完我們的中間件之后就是 app.listen(3000)
一起看下這個 listen 干了什么
這里的 http.createServer
就是 node 原生啟動 http 服務的方法,這里稍微擴展下基礎知識,此方法接受兩個參數(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 方法主要負責生成洋蔥模型,通過 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)引用層級關系,為使用者提供方便。
handleRequest 方法
還是 callback 中的展開解釋,看下 this.handleRequest(ctx, fn)
這部分做了什么
分別拿到 ctx 和 compose 生成的洋蔥模型,開始逐一消費中間件。
context.js 文件
上面理清了整體框架,下面看下 context.js
內(nèi)部的細節(jié),在文件結尾有兩大段的代理
這里可以看到所有的 req 及 res 的方法集合,那么哪些方法可讀,哪些可寫,哪些既可讀又可寫,哪些方法不允許修改
這就是 delegates
這個庫做的事情。
delegates
內(nèi)部利用了,__defineGetter__
和 __defineSetter__
方法控制讀寫,當然我們可以從中學習思想,也不能盲從
這兩個 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)用,感興趣可以自行閱讀源碼。
應用
智聯(lián)前端架構整體的 node 服務都基于 koa 實現(xiàn),包括我們的 vue 服務端渲染和 node restful api 等等。
我們選擇 koa 的原因是其本身輕巧,可擴展性良好,支持 async、await 的異步,徹底擺脫了回調(diào)地獄。
市面上也有成熟基于 koa2 的企業(yè)級解決方案,如 eggjs 和 thinkjs。
以上是“koa2怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。