中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

koa之中間件流程控制的示例分析

發布時間:2021-09-03 11:42:25 來源:億速云 閱讀:156 作者:小新 欄目:web開發

這篇文章主要為大家展示了“koa之中間件流程控制的示例分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“koa之中間件流程控制的示例分析”這篇文章吧。

1. koa中間件執行流程

關于koa中間件如何執行,官網上有一個非常經典的例子,有興趣的可以去看看,不過這里,我想把它修改的更簡單一點:

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的中間件執行機制,可以用下圖的洋蔥模型來形容:

koa之中間件流程控制的示例分析

通過這種執行流程,開發者可以非常方便的開發一些中間件,并且非常容易的整合到實際業務流程中。那么,這樣的流程又是如何實現和控制的呢?

2. koa中的generator和compose

簡單來說,洋蔥模型的執行流程是通過es6中的generator來實現的。不熟悉generator的同學可以去看看其特性,其中一個就是generator函數可以像打斷點一樣從函數某個地方跳出,之后還可以再回來繼續執行。下面一個例子可以說明這種特性:

var gen=function*(){
console.log('begin!');
//yield語句,在這里跳出,將控制權交給anotherfunc函數。
yield anotherfunc;
//下次回來時候從這里開始執行
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前后的語句最先和最后執行,yield中間的代碼在中心執行。

現在設想一下,如果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中間件寫法的感覺了呢?但是目前,我們還是一步一步手動的在執行我們這個洋蔥模型,能否寫一個函數,自動的來執行我們這個模型呢?

3. 讓洋蔥模型自動跑起來:一個run函數的編寫

上面例子中,最后的代碼我們可以看出一個規律,基本就是外層的generator調用next方法把控制權交給內層,內層再繼續調用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執行結束,返回。
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,其內部執行其實就是我們上一個例子的精簡,使用遞歸的方法執行。運行這個例子,可以看到結果和我們上一個例子相同。

到此為止,我們就基本講清楚了koa中的中間件洋蔥模型是如何自動執行的。事實上,koa中使用的co函數,一部分功能就是實現我們這里編寫的run函數的功能。

以上是“koa之中間件流程控制的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

koa
AI

蓝山县| 襄城县| 平泉县| 宁德市| 金乡县| 琼结县| 抚州市| 尼勒克县| 广南县| 兴山县| 陕西省| 茌平县| 南皮县| 哈尔滨市| 沙雅县| 冀州市| 广昌县| 绥宁县| 德阳市| 澎湖县| 镶黄旗| 武川县| 岫岩| 中阳县| 临安市| 高邮市| 珲春市| 常宁市| 鸡西市| 富民县| 利川市| 桐乡市| 天气| 巧家县| 靖安县| 兴城市| 雷山县| 宁国市| 延川县| 井冈山市| 大荔县|