Koa原始碼分析

2021-09-11 10:01:42 字數 2809 閱讀 8900

上篇文章寫了如何閱讀koa的原始碼, 粗略的過了一下koa的原始碼, 但是作為乙個沒有得出乙個具體的結論, 中介軟體的執行原理也不清楚, 這裡我們再仔細的過一遍koa的原始碼.

首先還是先過一遍例子

const koa = require('koa');

ctx.body = 'hello world';

});複製**

起乙個web服務, 來乙個hello world, 作為http模組的再封裝, 我們還是慢慢來挖掘它是如何封裝的吧(無關的**我都會刪掉).

首先是listen:

listen(...args) 

複製**

http模組我們都知道 無非是http.createserver(fn).listen(port), 其中fn帶著req, res. 根據上面的封裝我們可以肯定this.callback肯定是帶著請求以及進行響應了. 那麼再來看看this.callback吧.

callback() ;

return handlerequest;

}複製**

果然callback返回的函式是帶著req, res的, 那我繼續往下走看handlerequest究竟經歷了什麼,ctx大佬出現了, 我們在用koa的時候所有請求響應都是掛在ctx上的, 看起來ctx是通過createcontext建立的, 那就繼續看createcontext吧:

createcontext(req, res) );

request.ip = request.ips[0] || req.socket.remoteaddress || '';

context.accept = request.accept = accepts(req);

context.state = {};

return context;

}複製**

createcontext比較簡單, 就是把各種有用的沒用的變數掛到context上, **也很簡單, 但是因為涉及到request和response我們需要簡單看一下request.js和response.js:

module.exports = ,

//..more items

}複製**

都是很簡單獲取變數沒啥好說的, 那麼回到前面callback部分, ctx建立好了然後呼叫並返回了this.handlereques, 沒啥好說的, 繼續看唄:

handlerequest(ctx, fnmiddleware) 

複製**

這一部分略微複雜一點, 由上面看出來fnmiddleware是我們取出來的中介軟體, 然後我們把ctx傳到中介軟體裡執行, 跟我們的通常用法有點像了. 到這一步重點來了:中介軟體

在**中介軟體的原理之前, 不妨先來看看中介軟體是怎麼用的, 來個簡單的例子:

const koa = require('koa')

function

m1 (ctx, nex) )

function

m2 (ctx, nex) )

function

m3 (ctx, nex) )

複製**

上面的結果很明確了, 但是我們不妨來視覺化一下:

m1: 輸出m1

await1: m1你先暫停一下讓m2先走

m1: ...

m2: 輸出m2

await2: m2你也停一下讓m3先走

m2: ...(委屈)

m3: 輸出m3, 上面的注意啦要遠路返回了

m2: 輸出m2 end m1注意了我要返回啦

m1: 輸出m1 end

respond: ctx.body是hello world呢 就糊弄一下使用者返回吧

複製**

看到沒, ctx.body不代表立即響應, 僅僅是乙個我們後面會用到的變數, 也就是說我們的ctx過了一遍所有的中介軟體然後才會做出響應. 這裡不提await神奇的暫停效果, 我們就需要可以這麼用就行了. 那麼我們這個中介軟體是怎麼實現的呢, 來看compose.js:

function

compose (middleware) context

* @return

* @api public

*/return

function (context, next) ))}}}

複製**

看過我前一篇的可以知道這裡其實就是乙個遞迴. 但是跟connect的遞迴不一樣這裡是promise, 我們都知道await 跟promise搭配味道更佳嘛. 重點是這個next, 我們呼叫了await next之後, 程式非得等這個promise執行完不可, 我們來簡化一下中介軟體的模型:

promise.resolve(async m1 () )

console.log(m2 end)

})console.log(m1 end)

})複製**

是不是這樣一下就清楚了, 作為應用層的東西, 我們不需要去考慮async/await究竟是怎麼實現的, 只需要了解它實現了什麼樣的效果.

還是得佩服tj大神. 有問題可以互相交流哈.

Koa原始碼分析

先看看這個極簡的啟動 const koa require koa response ctx.body hello koa 我們在koa原始碼資料夾下建立index.js檔案,將上面的 寫入,並將require koa 換成require const koa require debugger ctx....

koa 原始碼分析

koa的用法,這裡就不在列舉了。我覺得koa主要功能主要是下面幾個方面 1 提供了中介軟體機制 2 封裝了request response,context物件 3 使用了yield,提供了便利的流程控制,使非同步程式設計更優雅 4 便捷的異常處理,使用try catch就可以捕獲程式中的異常,不需要...

Koa 原始碼分析

閱讀原始碼可以很好地提高自身水平,從 會用 到 掌握原理 的過程,也是自身從前端菜鳥到中高階高階的過程,在不少面試過程中,也會問到你有沒有閱讀過原始碼等問題。該場 chat 將會為大家分享一下看似很複雜,其實超級簡單的 node.js koa 框架。主要會分享以下內容 koa 封裝原生 http 模...