egg koa 中间件执行原理,洋葱模型原理

本文深入探讨了Koa.js的中间件机制,通过官方示例解析了中间件的使用方式,并详细解释了其洋葱模型的工作原理。文章还提供了Koa.js的源码级解析,帮助读者理解中间件如何串联执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.官网例子

const Koa = require('koa');
const app = new Koa();

// logger
app.use(async (ctx, next) => {
  await next();
  const rt = ctx.response.get('X-Response-Time');
  console.log(`${ctx.method} ${ctx.url} - ${rt}`);
});

// x-response-time
app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.set('X-Response-Time', `${ms}ms`);
});

// response
app.use(async ctx => {
  ctx.body = 'Hello World';
});

app.listen(3000);

2.源码

const http = require('http');

// 传入中间数据,返回可以递归执行中间件的函数
function compose(middlewareList) {
    return function (ctx) {
        function dispatch(i) {
           // 获取要执行的中间件函数,fn的第一个参数是上下文,第二个参数是next函数。
            const fn = middlewareList[i]  
            try {
           /* fn第二个参数传入dispatch函数,参数i+1,
           即会执行下一个中间件,但是上一个中间件只执行到next前,还在栈中。
           以此类推,所有中间件都进栈且都执行到next()函数前,
           此时,最后一个中间件在栈顶,所以最后一个中间件先执行完后弹栈;
           以此第一个中间件最后才执行完。从而形成洋葱模型。*/
                return Promise.resolve(
                    fn(ctx, dispatch.bind(null, i + 1))
                )
            } catch (err) {
                return Promise.reject(err)
            }
        }
        return dispatch(0)  //执行第一个中间件函数
    }
}

class koaMiddleWare {
    constructor() {
        this.middlewareList = []
    }

    // 添加中间件
    use(fn) {
        this.middlewareList.push(fn)
        return this
    }

    // 请求时执行次函数
    handleRequest(ctx, middleWare) {
        // 这个 middleWare 就是 compose 函数返回的 fn
        // 执行 middleWare(ctx) 其实就是执行中间件函数,然后再用 Promise.resolve 封装并返回
        return middleWare(ctx)
    }

    createContext(req, res) {
        const ctx = {
            req,
            res
        }
        return ctx
    }

    callback() {
        const fn = compose(this.middlewareList)
        return (req, res) => {
            const ctx = this.createContext(req, res)
            return this.handleRequest(ctx, fn)
        }
    }

    listen(...args) {
        const server = http.createServer(this.callback())
        return server.listen(...args);
    }
}

module.exports = koaMiddleWare
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值