摘要:本筆記共四篇源碼閱讀筆記源碼閱讀筆記源碼閱讀筆記服務(wù)器啟動(dòng)與請(qǐng)求處理源碼閱讀筆記對(duì)象起因前兩天終于把自己一直想讀的源代碼讀了一遍。首先放上關(guān)鍵的源代碼在上一篇源碼閱讀筆記服務(wù)器啟動(dòng)與請(qǐng)求處理中,我們已經(jīng)分析了的作用。
起因本筆記共四篇
Koa源碼閱讀筆記(1) -- co
Koa源碼閱讀筆記(2) -- compose
Koa源碼閱讀筆記(3) -- 服務(wù)器の啟動(dòng)與請(qǐng)求處理
Koa源碼閱讀筆記(4) -- ctx對(duì)象
前兩天終于把自己一直想讀的Koa源代碼讀了一遍。
今天就要來(lái)分析Koa的ctx對(duì)象,也就是在寫(xiě)中間件和處理請(qǐng)求和響應(yīng)時(shí)的那個(gè)this對(duì)象。
而這個(gè)this對(duì)象,也是和Express的重要區(qū)別之一。不用再區(qū)分req,res(雖然還是得知道),一個(gè)this對(duì)象就能調(diào)用所有方法。
在實(shí)際開(kāi)發(fā)中,是非常便利的。
在這兒則需要談一談Koa1和Koa2調(diào)用this對(duì)象的區(qū)別。
Koa1在調(diào)用時(shí),使用的是this,而Koa2則是ctx。
// Koa1 app.use(function * (next) { this.body = "hello world" yield next })
// Koa2 app.use(async (ctx, next) => { ctx.body = "hello world" await next() })
使用方式,只是把this換成了ctx。
具體為什么出現(xiàn)ctx和next,之前的文章koa-compose的分析有寫(xiě)。
這兒繼續(xù)以Koa1為例,因?yàn)榭吹枚甂oa1源代碼的,看Koa2的源碼自然也不難。
首先放上關(guān)鍵的源代碼:
app.callback = function(){ var fn = co.wrap(compose(this.middleware)); var self = this; return function(req, res){ res.statusCode = 404; var ctx = self.createContext(req, res); onFinished(res, ctx.onerror); fn.call(ctx).then(function () { respond.call(ctx); }).catch(ctx.onerror); } };
在上一篇Koa源碼閱讀筆記(3) -- 服務(wù)器の啟動(dòng)與請(qǐng)求處理中,我們已經(jīng)分析了fn的作用。
而onFinished則會(huì)在請(qǐng)求完成時(shí)調(diào)用,剩下的則是調(diào)用中間件去處理響應(yīng)。
同時(shí)var ctx = self.createContext(req, res);這一句,不看createContext這個(gè)函數(shù),應(yīng)該也能猜出它的作用。
之后的fn.call(ctx)則說(shuō)明了中間件中this的來(lái)源。
在這兒不得不感嘆一句,JavaScript的this真的是太靈活了,配合閉包,call,apply等,簡(jiǎn)直擁有無(wú)限魔力。
貼出相關(guān)的源代碼:
var response = require("./response"); var context = require("./context"); var request = require("./request"); /** * Initialize a new context. * * @api private */ app.createContext = function(req, res){ var context = Object.create(this.context); var request = context.request = Object.create(this.request); var response = context.response = Object.create(this.response); context.app = request.app = response.app = this; context.req = request.req = response.req = req; context.res = request.res = response.res = res; request.ctx = response.ctx = context; request.response = response; response.request = request; context.onerror = context.onerror.bind(context); context.originalUrl = request.originalUrl = req.url; context.cookies = new Cookies(req, res, { keys: this.keys, secure: request.secure }); context.accept = request.accept = accepts(req); context.state = {}; return context; };
雖然看上去有點(diǎn)繞,但是仔細(xì)看看,還是不難的。
之前說(shuō)過(guò),Koa的源碼簡(jiǎn)潔,一共就4個(gè)文件。
除了主要的Application.js, 剩下就都是與請(qǐng)求和響應(yīng)相關(guān)的了。
這兒,因?yàn)槊看味家獎(jiǎng)?chuàng)建并調(diào)用ctx對(duì)象。為了避免影響原有的context,request,response對(duì)象。
這兒采用了Object.create()來(lái)克隆對(duì)象。
首先就來(lái)分析,最開(kāi)始的context.js。
context的實(shí)現(xiàn)很簡(jiǎn)單,但有意思的地方在于delegate這個(gè)地方。
就如下圖所示:
我看了delegate這個(gè)源代碼,功能是把context中相應(yīng)的方法調(diào)用和屬性讀取,委托至某個(gè)對(duì)象中。
而不用自己一個(gè)一個(gè)的寫(xiě)apply,call等。
關(guān)于request和response,我這兒就不詳細(xì)寫(xiě)了。
在這兒放一張圖足以。
實(shí)際上,request和response是通過(guò)getter和setter,來(lái)實(shí)現(xiàn)存取不同屬性的功能。
另外,通過(guò)剛才說(shuō)的delegate方法,則使用ctx對(duì)象時(shí),便能自動(dòng)通過(guò)getter和setter獲取想要的內(nèi)容。
這一篇很簡(jiǎn)單,其實(shí)也沒(méi)啥可以說(shuō)的。
因?yàn)镵oa除了中間件部分看起來(lái)復(fù)雜,其它地方還是很簡(jiǎn)潔明了的。
學(xué)習(xí)源代碼的過(guò)程中,也發(fā)現(xiàn)了很多優(yōu)雅的寫(xiě)法,算是開(kāi)拓了自己的眼界。
從會(huì)寫(xiě)到寫(xiě)好,看來(lái)還要挺長(zhǎng)一段時(shí)間的。
前端路漫漫,且行且歌。
最后附上本人博客地址和原文鏈接,希望能與各位多多交流。
Lxxyx的前端樂(lè)園
原文鏈接:Koa源碼閱讀筆記(4) -- ctx對(duì)象
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/90861.html
摘要:本筆記共四篇源碼閱讀筆記源碼閱讀筆記源碼閱讀筆記服務(wù)器啟動(dòng)與請(qǐng)求處理源碼閱讀筆記對(duì)象起因前兩天閱讀了的基礎(chǔ),和中間件的基礎(chǔ)。的前端樂(lè)園原文鏈接源碼閱讀筆記服務(wù)器啟動(dòng)與請(qǐng)求處理 本筆記共四篇Koa源碼閱讀筆記(1) -- coKoa源碼閱讀筆記(2) -- composeKoa源碼閱讀筆記(3) -- 服務(wù)器の啟動(dòng)與請(qǐng)求處理Koa源碼閱讀筆記(4) -- ctx對(duì)象 起因 前兩天閱讀了K...
摘要:正好自己之前也想看的源代碼,所以趁著這個(gè)機(jī)會(huì),一口氣將其讀完。源碼解讀的源代碼十分簡(jiǎn)潔,一共才兩百余行。結(jié)語(yǔ)的源代碼讀取來(lái)不難,但其處理方式卻令人贊嘆。而且閱讀的源代碼,是閱讀源碼的必經(jīng)之路。 本筆記共四篇Koa源碼閱讀筆記(1) -- coKoa源碼閱讀筆記(2) -- composeKoa源碼閱讀筆記(3) -- 服務(wù)器の啟動(dòng)與請(qǐng)求處理Koa源碼閱讀筆記(4) -- ctx對(duì)象 起...
摘要:引言最近空閑時(shí)間讀了一下的源碼在閱讀的源碼的過(guò)程中,我的感受是代碼簡(jiǎn)潔思路清晰不得不佩服大神的水平。調(diào)用的時(shí)候就跟有區(qū)別使用必須使用來(lái)調(diào)用除了上面的的構(gòu)造函數(shù)外,還暴露了一些公用的,比如兩個(gè)常見(jiàn)的,一個(gè)是,一個(gè)是。 引言 最近空閑時(shí)間讀了一下Koa2的源碼;在閱讀Koa2(version 2.2.0)的源碼的過(guò)程中,我的感受是代碼簡(jiǎn)潔、思路清晰(不得不佩服大神的水平)。下面是我讀完之后...
摘要:于是抱著知其然也要知其所以然的想法,開(kāi)始閱讀的源代碼。問(wèn)題讀源代碼時(shí),自然是帶著諸多問(wèn)題的。源代碼如下在被處理完后,每當(dāng)有新請(qǐng)求,便會(huì)調(diào)用,去處理請(qǐng)求。接下來(lái)會(huì)繼續(xù)寫(xiě)一些閱讀筆記,因?yàn)榭吹脑创a確實(shí)是獲益匪淺。 本筆記共四篇Koa源碼閱讀筆記(1) -- coKoa源碼閱讀筆記(2) -- composeKoa源碼閱讀筆記(3) -- 服務(wù)器の啟動(dòng)與請(qǐng)求處理Koa源碼閱讀筆記(4) -...
摘要:接上次挖的坑,對(duì)相關(guān)的源碼進(jìn)行分析第一篇。和同為一批人進(jìn)行開(kāi)發(fā),與相比,顯得非常的迷你。在接收到一個(gè)請(qǐng)求后,會(huì)拿之前提到的與來(lái)創(chuàng)建本次請(qǐng)求所使用的上下文。以及如果沒(méi)有手動(dòng)指定,會(huì)默認(rèn)指定為。 接上次挖的坑,對(duì)koa2.x相關(guān)的源碼進(jìn)行分析 第一篇。 不得不說(shuō),koa是一個(gè)很輕量、很優(yōu)雅的http框架,尤其是在2.x以后移除了co的引入,使其代碼變得更為清晰。 express和ko...
閱讀 1985·2019-08-30 15:54
閱讀 3612·2019-08-29 13:07
閱讀 3136·2019-08-29 12:39
閱讀 1802·2019-08-26 12:13
閱讀 1556·2019-08-23 18:31
閱讀 2171·2019-08-23 18:05
閱讀 1861·2019-08-23 18:00
閱讀 1054·2019-08-23 17:15