1. 程式人生 > >express中介軟體系統的基本實現

express中介軟體系統的基本實現

一直覺得express的中介軟體系統這種流式處理非常形象,就好像加工流水線一樣,每個環節都在針對同一個產品的不同部分完成自己的工作,最後得到一個成品。今天就來實現一個簡易的【中介軟體佇列】。

一. API層

  • 初始化方法

    let middleware = new MiddleWare();
  • 新增中介軟體函式的方法

    //Fn為被新增的中介軟體
    middleware.use(Fn);
  • 啟動中介軟體佇列

    middleware.start(req, res);

二. 核心類的定義

class MiddleWare{
    constructor(){
        this.queue = [];//用來存放中介軟體佇列
    }
    
    //新增中介軟體
    use(fn){
         this.queue.push(fn);//將自定義中介軟體加入佇列
    }
    
    //按次序執行中介軟體
    start(req, res){
        let i = 0;//執行指標
        
        //執行器
        const next = (err)=>{
            //如果有錯誤就將錯誤資訊掛在response上並直接退出
            if(err){
                res.hasError = true;
                res.data = err.toString();
                return;
            }
            
            //如果沒有錯誤就檢視是否到達隊尾,若沒到則繼續執行下一個中介軟體
            if(i < this.queue.length){
                this.queue[i++](req, res, next);
                /*將next直接傳入當前執行的函式作為回撥
                 當前執行函式執行到任何一步,通過主動呼叫next方法即可將相關資訊傳給下一個中介軟體。*/
            }else{
                //如果已經到隊尾了則結束
                console.log('finish');
            }
            
        }
        //啟動第一個
        next();
    }
}

三. 使用use方法新增中介軟體

//新增第一個中介軟體
/*
此處演示了一個基本的錯誤捕捉的寫法,當中間件中出現錯誤時,會捕捉到錯誤並傳入next
*/
middleware.use(function(req, res, next){
    try{
       req.addon1 = 'I add something';  
    }catch(err){
       next(err);
    }
    next();
});

//新增第二個中介軟體
middleware.use(function(req, res, next){
     res.addon2 = 'I add something more';
     next();
});

//新增第三個中介軟體
middleware.use(function(req, res, next){
     if (req.addon2) {
       delete req.addon2;
     }
     res.addon3 = 'I add something a lot';
     next();
});

四. 消費定義的類

“消費”這個詞是最近學到的,覺得很裝X,所以也在這裡裝一下~

let req = {};
let res = {};
let result = middleware.start(req,res);
console.log(req, res);

五. 檢視執行結果

可以看到有錯誤發生和正常響應時的不同結果:

六. 在伺服器端執行

node起一個web伺服器那真是太隨意了~

const http = require('http');
//上面的一堆程式碼
http.createServer(function(req, res){
    let result = {};
    middleware.start(req, result);
    res.end(JSON.stringify(result));
}).listen(9527);

看一下效果(訪問伺服器時自定義訊息就可以傳至前臺了):