這篇文章主要為大家展示了“koa之中間件流程控制的示例分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“koa之中間件流程控制的示例分析”這篇文章吧。
創(chuàng)新互聯是一家集網站建設,九江企業(yè)網站建設,九江品牌網站建設,網站定制,九江網站建設報價,網絡營銷,網絡優(yōu)化,九江網站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯網需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網站。1. koa中間件執(zhí)行流程
關于koa中間件如何執(zhí)行,官網上有一個非常經典的例子,有興趣的可以去看看,不過這里,我想把它修改的更簡單一點:
var koa = require('koa'); var app = koa(); app.use(function*(next) { console.log('begin middleware 1'); yield next; console.log('end middleware 1'); }); app.use(function*(next) { console.log('begin middleware 2'); yield next; console.log('end middleware 2'); }); app.use(function*() { console.log('middleware 3'); }); app.listen(3000);
運行這個例子,然后使用curl工具,運行:
curl http://localhost:3000
可以看到,運行之后,會輸出:
begin middleware 1 begin middleware 2 middleware 3 end middleware 2 end middleware 1
這個例子非常形象的代表了koa的中間件執(zhí)行機制,可以用下圖的洋蔥模型來形容:
通過這種執(zhí)行流程,開發(fā)者可以非常方便的開發(fā)一些中間件,并且非常容易的整合到實際業(yè)務流程中。那么,這樣的流程又是如何實現和控制的呢?
2. koa中的generator和compose
簡單來說,洋蔥模型的執(zhí)行流程是通過es6中的generator來實現的。不熟悉generator的同學可以去看看其特性,其中一個就是generator函數可以像打斷點一樣從函數某個地方跳出,之后還可以再回來繼續(xù)執(zhí)行。下面一個例子可以說明這種特性:
var gen=function*(){ console.log('begin!'); //yield語句,在這里跳出,將控制權交給anotherfunc函數。 yield anotherfunc; //下次回來時候從這里開始執(zhí)行 console.log('end!'); } var anotherfunc(){ console.log('this is another function!'); } var g=gen(); var another=g.next(); //'begin!' //another是一個對象,其中value成員就是返回的anotherfunc函數 another.value(); //'this is another function!' g.next(); //'end!';
從這個簡單例子中,可以看出洋蔥模型最基本的一個雛形,即yield前后的語句最先和最后執(zhí)行,yield中間的代碼在中心執(zhí)行。
現在設想一下,如果yield后面跟的函數本身就又是一個generator,會怎么樣呢?其實就是從上面例子里面做一個引申:
var gen1=function*(){ console.log('begin!'); yield g2; console.log('end!'); } var gen2=function*(){ console.log('begin 2'); yield anotherfunc; console.log('end 2'); } var anotherfunc(){ console.log('this is another function!'); } var g=gen(); var g2=gen2(); var another1=g.next(); //'begin!'; var another2=another1.value.next(); //'begin 2'; another2.value(); //'this is another function!'; another1.value.next(); //'end 2'; g.next(); //'end!';
可以看出,基本上是用上面的例子,再加一個嵌套而已,原理是一樣的。
而在koa中,每個中間件generator都有一個next參數。在我們這個例子中,g2就可以看成是g函數的next參數。事實上,koa也確實是這樣做的,當使用app.use()掛載了所有中間件之后,koa有一個koa-compose模塊,用于將所有generator中間件串聯起來,基本上就是將后一個generator賦給前一個generator的next參數。koa-compose的源碼非常簡單短小,下面是我自己實現的一個:
function compose(middlewares) { return function(next) { var i = middlewares.length; var next = function*() {}(); while (i--) { next = middlewares[i].call(this, next); } return next; } }
使用我們自己寫的compose對上面一個例子改造,是的其更接近koa的形式:
function compose(middlewares) { return function(next) { var i = middlewares.length; var next = function*() {}(); while (i--) { next = middlewares[i].call(this, next); } return next; } } var gen1=function*(next){ console.log('begin!'); yield next; console.log('end!'); } var gen2=function*(next){ console.log('begin 2'); yield next; console.log('end 2'); } var gen3=function*(next){ console.log('this is another function!'); } var bundle=compose([gen1,gen2,gen3]); var g=bundle(); var another1=g.next(); //'begin!'; var another2=another1.value.next(); //'begin 2'; another2.value.next(); //'this is another function!'; another1.value.next(); //'end 2'; g.next(); //'end!';
怎么樣?是不是有一點koa中間件寫法的感覺了呢?但是目前,我們還是一步一步手動的在執(zhí)行我們這個洋蔥模型,能否寫一個函數,自動的來執(zhí)行我們這個模型呢?
3. 讓洋蔥模型自動跑起來:一個run函數的編寫
上面例子中,最后的代碼我們可以看出一個規(guī)律,基本就是外層的generator調用next方法把控制權交給內層,內層再繼續(xù)調用next把方法交給更里面的一層。整個流程可以用一個函數嵌套的寫法寫出來。話不多說,直接上代碼:
function run(gen) { var g; if (typeof gen.next === 'function') { g = gen; } else { g = gen(); } function next() { var tmp = g.next(); //如果tmp.done為true,那么證明generator執(zhí)行結束,返回。 if (tmp.done) { return; } else if (typeof g.next === 'function') { run(tmp.value); next(); } } next(); } function compose(middlewares) { return function(next) { var i = middlewares.length; var next = function*() {}(); while (i--) { next = middlewares[i].call(this, next); } return next; } } var gen1 = function*(next) { console.log('begin!'); yield next; console.log('end!'); } var gen2 = function*(next) { console.log('begin 2'); yield next; console.log('end 2'); } var gen3 = function*(next) { console.log('this is another function!'); } var bundle = compose([gen1, gen2, gen3]); run(bundle);
run函數接受一個generator,其內部執(zhí)行其實就是我們上一個例子的精簡,使用遞歸的方法執(zhí)行。運行這個例子,可以看到結果和我們上一個例子相同。
到此為止,我們就基本講清楚了koa中的中間件洋蔥模型是如何自動執(zhí)行的。事實上,koa中使用的co函數,一部分功能就是實現我們這里編寫的run函數的功能。
以上是“koa之中間件流程控制的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注創(chuàng)新互聯成都網站設計公司行業(yè)資訊頻道!
另外有需要云服務器可以了解下創(chuàng)新互聯scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
網頁題目:koa之中間件流程控制的示例分析-創(chuàng)新互聯
分享鏈接:http://jinyejixie.com/article18/dchddp.html
成都網站建設公司_創(chuàng)新互聯,為您提供營銷型網站建設、App開發(fā)、定制開發(fā)、小程序開發(fā)、云服務器、網站制作
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯