一步步去閱讀koa原始碼,中介軟體執行原理

2021-09-13 15:27:48 字數 3642 閱讀 8845

koa的中介軟體執行的流程控制,**的是非常精妙的。由下面的一張洋蔥模型的圖來形容,記住這張圖。

為什麼是這樣子的圖,下面我們有乙個例子來描述一下

const koa = require('koa')

// fn1

console.log('fn1-1')

next()

console.log('fn1-2')

})// fn2

console.log('fn2-1')

next()

console.log('fn2-2')

})// fn3

console.log('fn3-1')

next()

console.log('fn3-2')

})// fn1-1、fn2-1、fn3-1、fn3-2、fn2-2、fn1-2

上面的這個例子,順序列印出來的是fn1-1、fn2-1、fn3-1、fn3-2、fn2-2、fn1-2,現在只知道,呼叫next()函式就會把控制流程就跳到下乙個中介軟體,知道執行所有完之後然後再逐步向上執行前乙個next後面的**。這根跟洋蔥有很大的相像似性(如果你願意一層一層一層的剝開我的心~~~)。

但是其中的原理是什麼呢??下面我們一步步去探索。

constructor() 

use(fn)

就是把所有函式push到乙個middleware的陣列之中,這個use就是專門幹這中勾當的。

好了知道use的作用了,執行了use之後 我們的middleware中就有很多中介軟體函式了,下面我們繼續看下去。

listen(...args)
我們看到裡麼有個this.callback()執行函式,然後我們跳到這個函式裡面。

callback() ;

return handlerequest;

}

這個callback函式裡面,執行了compose函式,並且把middleware陣列作為引數傳遞進去。

執行到了compose函式,下面我們就看看compose裡面有什麼。

compose函式就是一開始引用了koa-compose模組,簡化之後發現裡面的**如下,簡化後就簡簡單單的20幾行**,後面會詳細解釋下面的**。

function compose (middleware) ))

} catch (err) }}}

執行這個compose返回乙個函式,這也是最核心的乙個函式。注意這是上面的callback呼叫的。得到乙個fn函式

看上面的callback呼叫的

然後執行到this.handlerequest(ctx, fn);這個函式吧ctxfn(這個就是上面compose返回的函式)作為引數,傳入到this.handlerequest中。 **如下。

handlerequest(ctx, fnmiddleware)
到這裡才真正的執行了compose返回的函式,把ctx傳進去。然後我們繼續看這個函式fnmiddleware(ctx),其實就是下面這樣子的。

function (context, next) ))

} catch (err)

}}

上面的**是這個部分的精華。這裡詳細的說一下,首先定義了乙個indexdispatch函式, 然後一開始呼叫dispatch(0)函式,裡面把0賦值給了index,然後從middleware的陣列(例子中我們有三個中介軟體函式)中拿到第0個中介軟體函式,賦值給fn,經過兩個if都不符合條件,然後執行

return promise.resolve(fn(context, function next () ))
這裡的執行fn中介軟體函式,並且把ctxfunction next () )作為引數傳遞進去。這個時候**如下一幕了然

console.log('fn1-1')

next() // 執行傳入的next

console.log('fn1-2')})

執行這個函式 就會列印出fn1-1然後就會執行next()函式,看上上一塊**,執行next()函式裡面會呼叫dispatch(i + 1)也就是呼叫第fn = middleware[1]正是第二個中介軟體。

看到這裡大家就大概明白了。然後進入第二個中介軟體執行fn,列印出fn2-1,繼續執行next()函式,next函式裡面繼續呼叫dispatch(i + 1)

也就是fn = middleware[2]第三中介軟體函式,列印出fn3-1,繼續執行next()函式裡面會呼叫dispatch(i + 1),也就是fn = middleware[3]

這裡注意了,if (i === middleware.length) fn = next到這裡會符合這個條件,然後把next賦值給fn這裡的next就是這個fnmiddleware(ctx).then(handleresponse).catch(onerror);呼叫時候傳入的,然而這裡並沒有傳入,所以這時候fn就是undefined,然後繼續執行到if (!fn) return promise.resolve()返回乙個空的值,這就是第三個中介軟體的next執行結果,

然後繼續執行下一行就列印出了fn3-2,最後向上執行到fn2-2,然後到fn1-2, 整個中介軟體的執行過程。很像洋蔥模型,一層層進入,然後一層層出來。

好了整個中介軟體執行過程就是醬紫啦~~~

最後安利一波部落格:

一步步去閱讀koa原始碼,中介軟體執行原理

koa的中介軟體執行的流程控制,的是非常精妙的。由下面的一張洋蔥模型的圖來形容,記住這張圖。為什麼是這樣子的圖,下面我們有乙個例子來描述一下 const koa require koa fn1 console.log fn1 1 next console.log fn1 2 fn2 console....

一步步學ROS

最近因為看svo的 裡面用到catkin決定要好好看ros,年前學會基本操作。啟動節點 rosrun package name executable name 檢視節點 rosnode list 注 rosout 節點是乙個特殊的節點,通過 roscore 自動啟動 檢視特定節點的資訊 rosnod...

windows Thrift c 一步步搭建

1.thrift 原始碼路徑 2.libevent原始碼路徑 3.boost路徑 安裝 conan install boost 1.68.0 conan stable 4.openssl路徑 安裝 conan install openssl 1.1.1a conan stable conan安裝bo...