成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

深入koa源碼(一):架構(gòu)設(shè)計(jì)

blankyao / 3145人閱讀

摘要:本文來(lái)自心譚博客深入源碼架構(gòu)設(shè)計(jì)前端面試設(shè)計(jì)模式手冊(cè)教程實(shí)戰(zhàn)等更多專(zhuān)題,請(qǐng)來(lái)導(dǎo)航頁(yè)領(lǐng)取食用所有系列文章都放在了。歡迎交流和最近讀了的源碼,理清楚了架構(gòu)設(shè)計(jì)與用到的第三方庫(kù)。

本文來(lái)自《心譚博客·深入koa源碼:架構(gòu)設(shè)計(jì)》
前端面試、設(shè)計(jì)模式手冊(cè)、Webpack4教程、NodeJs實(shí)戰(zhàn)等更多專(zhuān)題,請(qǐng)來(lái)導(dǎo)航頁(yè)領(lǐng)取食用
所有系列文章都放在了Github。歡迎交流和Star ?? ヽ(°▽°)ノ ?

最近讀了 koa 的源碼,理清楚了架構(gòu)設(shè)計(jì)與用到的第三方庫(kù)。本系列將分為 3 篇,分別介紹 koa 的架構(gòu)設(shè)計(jì)和 3 個(gè)核心庫(kù)的原理,最終會(huì)手動(dòng)實(shí)現(xiàn)一個(gè)簡(jiǎn)易的 koa。

koa 的實(shí)現(xiàn)都在倉(cāng)庫(kù)的lib目錄下,如下圖所示,只有 4 個(gè)文件:

對(duì)于這四個(gè)文件,根據(jù)用途和封裝邏輯,可以分為 3 類(lèi):req 和 res,上下文以及 application。

req 和 res

對(duì)應(yīng)的文件是:request.jsresponse.js。分別代表著客戶端請(qǐng)求信息和服務(wù)端返回信息。

這兩個(gè)文件在實(shí)現(xiàn)邏輯上完全一致。對(duì)外暴露都是一個(gè)對(duì)象,對(duì)象上的屬性都使用了gettersetter來(lái)實(shí)現(xiàn)讀寫(xiě)控制。

上下文

對(duì)應(yīng)的文件是:context.js。存了運(yùn)行環(huán)境的上下文信息,例如cookies。

除此之外,因?yàn)?b>request和response都屬于上下文信息,所以通過(guò)delegate.js庫(kù)來(lái)實(shí)現(xiàn)了對(duì)request.jsresponse.js上所有屬性的代理。例如以下代碼:

/**
 * Response delegation.
 */
delegate(proto, "response")
  .method("attachment")
  .method("redirect");

/**
 * Request delegation.
 */

delegate(proto, "request")
  .method("acceptsLanguages")
  .method("acceptsEncodings");

使用代理的另外一個(gè)好處就是:更方便的訪問(wèn) req 和 res 上的屬性。比如在開(kāi)發(fā) koa 應(yīng)用的時(shí)候,可以通過(guò)ctx.headers來(lái)讀取客戶端請(qǐng)求的頭部信息,不需要寫(xiě)成ctx.res.headers了(這樣寫(xiě)沒(méi)錯(cuò))。

注意:req 和 res 并不是在context.js中被綁定到上下文的,而是在application被綁定到上下文變量ctx中的。原因是因?yàn)槊總€(gè)請(qǐng)求的 req/res 都不是相同的。

Application

對(duì)應(yīng)的文件是: application.js。這個(gè)文件的邏輯是最重要的,它的作用主要是:

給用戶暴露服務(wù)啟動(dòng)接口

針對(duì)每個(gè)請(qǐng)求,生成新的上下文

處理中間件,將其串聯(lián)

對(duì)外暴露接口

使用 koa 時(shí)候,我們常通過(guò)listen或者callback來(lái)啟動(dòng)服務(wù)器:

const app = new Koa();
app.listen(3000); // listen啟動(dòng)
http.createServer(app.callback()).listen(3000); // callback啟動(dòng)

這兩種啟動(dòng)方法是完全等價(jià)的。因?yàn)?b>listen方法內(nèi)部,就調(diào)用了callback,并且將它傳給http.createServer。接著看一下callback這個(gè)方法主要做了什么:

調(diào)用koa-compose將中間件串聯(lián)起來(lái)(下文再講)。

生成傳給http.createServer()的函數(shù),并且返回。

http.createServer傳給函數(shù)參數(shù)的請(qǐng)求信息和返回信息,都被這個(gè)函數(shù)拿到了。并且傳給createContext方法,生成本次請(qǐng)求的上下文。

將生成的上下文傳給第 1 步生成的中間件調(diào)用鏈,這就是為什么我們?cè)谥虚g件處理邏輯的時(shí)候能夠訪問(wèn)ctx

生成新的上下文

這里上下文的方法對(duì)應(yīng)的是createContext方法。這里我覺(jué)得更像語(yǔ)法糖,是為了讓 koa 使用者使用更方便。比如以下這段代碼:

// this.request 是 request.js 暴露出來(lái)的對(duì)象,將其引用保存在context.request中
// 用戶可以直接通過(guò) ctx.屬性名 來(lái)訪問(wèn)對(duì)應(yīng)屬性
const request = (context.request = Object.create(this.request));

// 這個(gè)req是本次請(qǐng)求信息,是由 http.createServer 傳遞給回調(diào)函數(shù)的
context.req = request.req = response.req = req;

讀到這里,雖然可以解釋 ctx.headersctx.request.headers 的語(yǔ)法糖這類(lèi)問(wèn)題。但是感覺(jué)怪怪的。就以這個(gè)例子,ctx.headers 訪問(wèn)的是 ctx.reqeust 上的 headers,而不是本次請(qǐng)求信息上的headers。本次請(qǐng)求信息掛在了ctx.req上。

讓我們?cè)倩氐?b>reqeust.js的源碼,看到了headers的 getter 實(shí)現(xiàn):

get headers() {
  return this.req.headers;
}

ok,看來(lái)這里的this就是指的上下文環(huán)境咯。那么肯定是在application.js中某個(gè)地方改變了this的指向。果然,在application.js的構(gòu)造函數(shù)中可以看到:

this.request = Object.create(request);

application 實(shí)例上的 request 被傳遞給了 context.request,此時(shí) this 自然指向了 context。

可以看到,koa 為了讓開(kāi)發(fā)者使用方便,在上下文上做了很多工作。

中間件機(jī)制

中間件的設(shè)計(jì)是 koa 最重要的部分,實(shí)現(xiàn)上用到了koa-compose庫(kù)來(lái)串聯(lián)中間件,形成“洋蔥模型”。關(guān)于這個(gè)庫(kù),放在第二篇關(guān)于 koa 核心庫(kù)的介紹中說(shuō)明。

application 中處理中間件的函數(shù)是usehandleRequest

use函數(shù):傳入async/await函數(shù),并將其放入 application 實(shí)例上的middleware數(shù)組中。如果傳入是 generator,會(huì)調(diào)用koa-conver庫(kù)將其轉(zhuǎn)化為async/await函數(shù)。

handleRequest(ctx, fnMiddleware)函數(shù):傳入的fnMiddleware是已經(jīng)串聯(lián)好的中間件,函數(shù)所做的工作就是再其后再添加一個(gè)返回給客戶端的函數(shù)和錯(cuò)誤處理函數(shù)。返回給客戶端的函數(shù)其實(shí)就是respond函數(shù),里面通過(guò)調(diào)用res.end()來(lái)向客戶端返回信息,整個(gè)流程就走完了。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104916.html

相關(guān)文章

  • 深入koa源碼(二):核心庫(kù)原理

    摘要:最近讀了的源碼,理清楚了架構(gòu)設(shè)計(jì)與用到的第三方庫(kù)。本系列將分為篇,分別介紹的架構(gòu)設(shè)計(jì)和個(gè)核心庫(kù),最終會(huì)手動(dòng)實(shí)現(xiàn)一個(gè)簡(jiǎn)易的。本文來(lái)自心譚博客深入源碼核心庫(kù)原理所有系列文章都放在了。這一段邏輯封裝在了核心庫(kù)里面。 最近讀了 koa2 的源碼,理清楚了架構(gòu)設(shè)計(jì)與用到的第三方庫(kù)。本系列將分為 3 篇,分別介紹 koa 的架構(gòu)設(shè)計(jì)和 3 個(gè)核心庫(kù),最終會(huì)手動(dòng)實(shí)現(xiàn)一個(gè)簡(jiǎn)易的 koa。這是系列第 2...

    tyheist 評(píng)論0 收藏0
  • 步步去閱讀koa源碼,整體架構(gòu)分析

    摘要:閱讀好的框架的源碼有很多好處,從大神的視角去理解整個(gè)框架的設(shè)計(jì)思想。使用其實(shí)某個(gè)框架閱讀源碼的時(shí)候,首先我們要會(huì)去用這個(gè)框架,因?yàn)橛昧宋覀儾胖?,某個(gè)是怎么用,哪里有坑,哪里設(shè)計(jì)的精妙。 閱讀好的框架的源碼有很多好處,從大神的視角去理解整個(gè)框架的設(shè)計(jì)思想。大到架構(gòu)設(shè)計(jì),小到可取的命名風(fēng)格,還有設(shè)計(jì)模式、實(shí)現(xiàn)某類(lèi)功能使用到的數(shù)據(jù)結(jié)構(gòu)和算法等等。 使用koa 其實(shí)某個(gè)框架閱讀源碼的時(shí)候,首...

    haoguo 評(píng)論0 收藏0
  • 步步去閱讀koa源碼,整體架構(gòu)分析

    摘要:閱讀好的框架的源碼有很多好處,從大神的視角去理解整個(gè)框架的設(shè)計(jì)思想。使用其實(shí)某個(gè)框架閱讀源碼的時(shí)候,首先我們要會(huì)去用這個(gè)框架,因?yàn)橛昧宋覀儾胖?,某個(gè)是怎么用,哪里有坑,哪里設(shè)計(jì)的精妙。 閱讀好的框架的源碼有很多好處,從大神的視角去理解整個(gè)框架的設(shè)計(jì)思想。大到架構(gòu)設(shè)計(jì),小到可取的命名風(fēng)格,還有設(shè)計(jì)模式、實(shí)現(xiàn)某類(lèi)功能使用到的數(shù)據(jù)結(jié)構(gòu)和算法等等。 使用koa 其實(shí)某個(gè)框架閱讀源碼的時(shí)候,首...

    chaos_G 評(píng)論0 收藏0
  • 【全文】狼叔:如何正確的學(xué)習(xí)Node.js

    摘要:感謝大神的免費(fèi)的計(jì)算機(jī)編程類(lèi)中文書(shū)籍收錄并推薦地址,以后在倉(cāng)庫(kù)里更新地址,聲音版全文狼叔如何正確的學(xué)習(xí)簡(jiǎn)介現(xiàn)在,越來(lái)越多的科技公司和開(kāi)發(fā)者開(kāi)始使用開(kāi)發(fā)各種應(yīng)用。 說(shuō)明 2017-12-14 我發(fā)了一篇文章《沒(méi)用過(guò)Node.js,就別瞎逼逼》是因?yàn)橛腥嗽谥跎虾贜ode.js。那篇文章的反響還是相當(dāng)不錯(cuò)的,甚至連著名的hax賀老都很認(rèn)同,下班時(shí)讀那篇文章,竟然坐車(chē)的還坐過(guò)站了。大家可以很...

    Edison 評(píng)論0 收藏0
  • 【全文】狼叔:如何正確的學(xué)習(xí)Node.js

    摘要:感謝大神的免費(fèi)的計(jì)算機(jī)編程類(lèi)中文書(shū)籍收錄并推薦地址,以后在倉(cāng)庫(kù)里更新地址,聲音版全文狼叔如何正確的學(xué)習(xí)簡(jiǎn)介現(xiàn)在,越來(lái)越多的科技公司和開(kāi)發(fā)者開(kāi)始使用開(kāi)發(fā)各種應(yīng)用。 說(shuō)明 2017-12-14 我發(fā)了一篇文章《沒(méi)用過(guò)Node.js,就別瞎逼逼》是因?yàn)橛腥嗽谥跎虾贜ode.js。那篇文章的反響還是相當(dāng)不錯(cuò)的,甚至連著名的hax賀老都很認(rèn)同,下班時(shí)讀那篇文章,竟然坐車(chē)的還坐過(guò)站了。大家可以很...

    fengxiuping 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<