摘要:任何一層報(bào)錯(cuò),都能用捕獲總結(jié)是一個(gè)非常輕量級的框架,只實(shí)現(xiàn)了中間件處理流程和對對象的封裝。其他的功能都由外部中間件提供。
koa 的中間件機(jī)制巧妙的運(yùn)用了閉包和 async await 的特點(diǎn),形成了一個(gè)洋蔥式的流程,和 JS 的事件流 (捕獲 -> target -> 冒泡) 相似
handleRequest(ctx, fnMiddleware) { const res = ctx.res; res.statusCode = 404; const onerror = err => ctx.onerror(err); const handleResponse = () => respond(ctx); onFinished(res, onerror); return fnMiddleware(ctx).then(handleResponse).catch(onerror); }
上述代碼是 request 事件的句柄,也就是說每一個(gè)請求到來,都會執(zhí)行這個(gè)總方法
onerror 為請求設(shè)置了錯(cuò)誤處理的方法
handleResponse 是當(dāng)中間件完成后給瀏覽器返回 response 的方法,里面是原生的 res.end(body)
onFinished 是判斷請求最終有沒有完成,根據(jù)不同的結(jié)果采取不同的策略
fnMiddleware(ctx) 就是執(zhí)行所有中間件函數(shù),然后返回一個(gè) Promise 對象,不出錯(cuò)的話執(zhí)行 handleResponse
洋蔥式的中間件值得一提的是,中間件原理的代碼并沒有放在 koa 中,而是多帶帶打了一個(gè)模塊,叫做 ==koa-compose==
function (context, next) { // last called middleware # let index = -1 return dispatch(0) function dispatch (i) { if (i <= index) return Promise.reject(new Error("next() called multiple times")) index = i let fn = middleware[i] if (i === middleware.length) fn = next // 返回給 next() if (!fn) return Promise.resolve() try { // 返回給 next(),最外一層返回給 fnMiddleware(ctx).then(handleResponse) return Promise.resolve(fn(context, function next () { // 返回給外一層 fn 的 await return dispatch(i + 1) })) } catch (err) { return Promise.reject(err) } } }
執(zhí)行一次 dispatch 就是執(zhí)行一個(gè)中間件,算是洋蔥的一層
每個(gè) dispatch 都會返回一個(gè) Promise.resolve 給外面一層的 await(除了第一次,他返回給的是 fnMiddleware(ctx).then(handleResponse))
每個(gè) dispatch 都有一個(gè)自己的序號,也就是參數(shù) i (他用閉包控制住了) ,從 0 開始
閉包里有一個(gè) index,是記錄執(zhí)行過的中間件數(shù)量。一旦有序號大于數(shù)量,說明有中間件執(zhí)行了兩次 await next,這是不被允許的
每一層用 Promise.resolve 包裹是因?yàn)?await 需要接收一個(gè) Promise 對象
下面就是中間件原理的展開寫法,仔細(xì)琢磨吧
function dispatch(0){ // 第一層的序號 return Promise.resolve(async function a0(){ cnosole.log("0-0") await 111(function next0(){ return (function dispatch(1){ // 第二層的序號 return Promise.resolve(async function a1(){ cnosole.log("1-0") await 222(function next1(){ return (function dispatch(2){ // 第三層的序號 return Promise.resolve(async function a2(){ cnosole.log("2-0") await 333(function next2(){ return (function dispatch(3){ // i == middleware.length ,算是洋蔥芯吧 // fn[3] == undefined,說明中間件已經(jīng)到洋蔥的最里面了,開始向外返回 return Promise.resolve() })() })()333 console.log("2-1") }) })() })()222 console.log("1-1") }) })() })()111 console.log("0-1") }) } dispatch(0).then(handleResponse)思考 1. 普通函數(shù)采用 dispatch 算法也能取得洋蔥式的流程,為何要使用 async ?
app.use(async function (ctx,next) { console.log("1-1") await new Promise(function(resolve, reject){ setTimeout(function () { console.info ("wait for 10 mini seconds."); resolve(); },10); }); console.log("1-2") next(); console.log("1-3") }) app.use(async function (ctx,next) { console.log("2-1") await new Promise(function(resolve){ setTimeout(function () { console.info ("wait for 10 mini seconds"); resolve(); },10); }); console.log("2-2") next(); console.log("2-3") })
試試 next() 前面加上 await 和不加 await 的區(qū)別就明白了2. 為何要用 Promise.resolve 返回
因?yàn)樗茄笫[式的層級,如果用普通的 Boolean 返回的話,只能返回到上一層,沒法全局獲取,對錯(cuò)誤的把控難以控制。Promise 任何一層報(bào)錯(cuò),都能用 catch 捕獲總結(jié)
koa 是一個(gè)非常輕量級的框架,只實(shí)現(xiàn)了中間件處理流程和對 res、req 對象的封裝。其他的功能都由外部中間件提供。代碼不是很多,但是很精妙,對于代碼能力的提高有不小的幫助END
?
?
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/94307.html
摘要:啟動流程主要的啟動流程就是下面的步引入包實(shí)例化編寫中間件監(jiān)聽服務(wù)器引入包引入包其實(shí)就是引入的一個(gè)繼承于原生的類的類其中就包含了等原型方法實(shí)例化執(zhí)行,將等對象封裝在實(shí)例中編寫中間件首先判斷的類型,不是方法直接拋錯(cuò)是生成器函數(shù)的話用封裝是函數(shù) 啟動流程 koa 主要的啟動流程就是下面的 4 步:引入 koa 包 => 實(shí)例化 koa => 編寫中間件 => 監(jiān)聽服務(wù)器 const koa ...
摘要:實(shí)現(xiàn)的四大模塊上文簡述了源碼的大體框架結(jié)構(gòu),接下來我們來實(shí)現(xiàn)一個(gè)的框架,筆者認(rèn)為理解和實(shí)現(xiàn)一個(gè)框架需要實(shí)現(xiàn)四個(gè)大模塊,分別是封裝創(chuàng)建類構(gòu)造函數(shù)構(gòu)造對象中間件機(jī)制和剝洋蔥模型的實(shí)現(xiàn)錯(cuò)誤捕獲和錯(cuò)誤處理下面我們就逐一分析和實(shí)現(xiàn)。 什么是koa框架? ? ? ? ?koa是一個(gè)基于node實(shí)現(xiàn)的一個(gè)新的web框架,它是由express框架的原班人馬打造的。它的特點(diǎn)是優(yōu)雅、簡潔、表達(dá)力強(qiáng)、自由度...
摘要:實(shí)現(xiàn)的四大模塊上文簡述了源碼的大體框架結(jié)構(gòu),接下來我們來實(shí)現(xiàn)一個(gè)的框架,筆者認(rèn)為理解和實(shí)現(xiàn)一個(gè)框架需要實(shí)現(xiàn)四個(gè)大模塊,分別是封裝創(chuàng)建類構(gòu)造函數(shù)構(gòu)造對象中間件機(jī)制和剝洋蔥模型的實(shí)現(xiàn)錯(cuò)誤捕獲和錯(cuò)誤處理下面我們就逐一分析和實(shí)現(xiàn)。 什么是koa框架? ? ? ? ?koa是一個(gè)基于node實(shí)現(xiàn)的一個(gè)新的web框架,它是由express框架的原班人馬打造的。它的特點(diǎn)是優(yōu)雅、簡潔、表達(dá)力強(qiáng)、自由度...
閱讀 2786·2021-11-02 14:42
閱讀 3170·2021-10-08 10:04
閱讀 1188·2019-08-30 15:55
閱讀 1032·2019-08-30 15:54
閱讀 2321·2019-08-30 15:43
閱讀 1685·2019-08-29 15:18
閱讀 870·2019-08-29 11:11
閱讀 2369·2019-08-26 13:52