欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

koa2 從入門(mén)到精通(小結(jié))

 更新時(shí)間:2019年07月23日 10:10:50   作者:智聯(lián)大前端  
這篇文章主要介紹了koa2 從入門(mén)到精通,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

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

介紹

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

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

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

Hello Word

任何語(yǔ)言、框架都存在 Hello Word 示例,來(lái)表達(dá)其最簡(jiǎn)單的入門(mén) Demo,代碼如下

此時(shí)訪(fǎng)問(wèn)瀏覽器 localhost:3000,我們會(huì)看到打印出了 Hello Word,此時(shí)一個(gè)基于 koa 的服務(wù)就啟動(dòng)完成了。

上下文

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

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

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

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

中間件

先來(lái)看一個(gè)官方的例子:

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

進(jìn)入第一個(gè)中間件next() 跳到下一個(gè)中間件new Data() 記錄當(dāng)前時(shí)間next() 跳到下一個(gè)中間件將 ctx.body 賦值回到上一個(gè)中間件再次記錄當(dāng)前時(shí)間并計(jì)算時(shí)間差存到 http header 中回到上一個(gè)中間件將 header 中的 X-Response-time 打印出來(lái)

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

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

源碼解析

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

koa 源碼的 lib 目錄十分簡(jiǎn)單

lib
 |- application.js
 |- context.js
 |- request.js
 |- response.js

Application 類(lèi)初始化

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

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

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

use 方法

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

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

此時(shí)心中有沒(méi)有大寫(xiě)的 WHAT?

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

listen 方法

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

一起看下這個(gè) listen 干了什么

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

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

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

這個(gè) callback 中的信息量有點(diǎn)大,代碼本身并不難理解,注釋也有說(shuō)明,從這里展開(kāi)從上到下分別解釋

compose 方法

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

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

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

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

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

createContext 方法

callback 中的展開(kāi)解釋?zhuān)聪?const ctx = this.createContext(req, res) 做了什么

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

handleRequest 方法

還是 callback 中的展開(kāi)解釋?zhuān)聪?this.handleRequest(ctx, fn) 這部分做了什么

分別拿到 ctx 和 compose 生成的洋蔥模型,開(kāi)始逐一消費(fèi)中間件。

context.js 文件

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

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

這就是 delegates 這個(gè)庫(kù)做的事情。

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

這兩個(gè) api 去 MDN 上搜索會(huì)給出相同的警告信息

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

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

其它

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

應(yīng)用

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

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

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

總結(jié)

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Node.js與Sails redis組件的使用教程

    Node.js與Sails redis組件的使用教程

    這篇文章主要介紹了Node.js與Sails redis組件的使用教程,主要介紹幾個(gè)用法,為string,set,hash和list的使用。需要的朋友可以參考下
    2017-02-02
  • 在node.js中怎么屏蔽掉favicon.ico的請(qǐng)求

    在node.js中怎么屏蔽掉favicon.ico的請(qǐng)求

    這篇文章主要介紹了在node.js中怎么屏蔽掉favicon.ico的請(qǐng)求,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-03-03
  • node.js中的http.response.setHeader方法使用說(shuō)明

    node.js中的http.response.setHeader方法使用說(shuō)明

    這篇文章主要介紹了node.js中的http.response.setHeader方法使用說(shuō)明,本文介紹了http.response.setHeader的方法說(shuō)明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • node.js中的fs.appendFile方法使用說(shuō)明

    node.js中的fs.appendFile方法使用說(shuō)明

    這篇文章主要介紹了node.js中的fs.appendFile方法使用說(shuō)明,本文介紹了fs.appendFile方法說(shuō)明、語(yǔ)法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • Node Puppeteer圖像識(shí)別實(shí)現(xiàn)百度指數(shù)爬蟲(chóng)的示例

    Node Puppeteer圖像識(shí)別實(shí)現(xiàn)百度指數(shù)爬蟲(chóng)的示例

    本篇文章主要介紹了Node Puppeteer圖像識(shí)別實(shí)現(xiàn)百度指數(shù)爬蟲(chóng)的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • Node.js連接mongo數(shù)據(jù)庫(kù)上傳文件的方法步驟

    Node.js連接mongo數(shù)據(jù)庫(kù)上傳文件的方法步驟

    本文主要介紹了Node.js連接mongo數(shù)據(jù)庫(kù)上傳文件的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • node.js + socket.io 實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)隨機(jī)匹配聊天

    node.js + socket.io 實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)隨機(jī)匹配聊天

    這篇文章主要介紹了node.js + socket.io 實(shí)現(xiàn)點(diǎn)對(duì)點(diǎn)隨機(jī)匹配聊天,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 使用NODE.JS創(chuàng)建一個(gè)WEBSERVER(服務(wù)器)的步驟

    使用NODE.JS創(chuàng)建一個(gè)WEBSERVER(服務(wù)器)的步驟

    在 node.js 中創(chuàng)建一個(gè)服務(wù)器非常簡(jiǎn)單,只需要使用 node.js 為我們提供的 http 模塊及相關(guān) API 即可創(chuàng)建一個(gè)麻雀雖小但五臟俱全的web 服務(wù)器,相比 Java/Python/Ruby 搭建web服務(wù)器的過(guò)程簡(jiǎn)單的很。本文簡(jiǎn)單的講解下實(shí)現(xiàn)步驟
    2021-06-06
  • node實(shí)現(xiàn)定時(shí)發(fā)送郵件的示例代碼

    node實(shí)現(xiàn)定時(shí)發(fā)送郵件的示例代碼

    本篇文章主要介紹了node實(shí)現(xiàn)定時(shí)發(fā)送郵件的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 從零學(xué)習(xí)node.js之文件操作(三)

    從零學(xué)習(xí)node.js之文件操作(三)

    這篇文章主要給大家介紹了關(guān)于node.js中對(duì)文件和目錄的操作,我們不一個(gè)個(gè)講每個(gè)api的使用,只是從幾個(gè)例子來(lái)了解下下文件系統(tǒng)。需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-02-02

最新評(píng)論