洋葱模型--koa中间件执行顺序的大管家!
什么是Koa洋葱模型
相信大家用过Koa或Express的小伙伴都对中间件很熟悉,特别是在Koa中的“洋葱模型”,这个模型的出现让Koa框架一直在前端领域占据重要的地位。
Koa 是一个基于 Node.js 的轻量级 Web 开发框架,Koa 的中间件机制采用了一种被称为“洋葱模型”的设计模式。
洋葱模型的执行过程
在 Koa 中,中间件的执行流程可以形象地比作剥洋葱
的过程,在代码的底层实现中是用递归
来实现的。
引入官方的照片我们可以更好的理解这一模型:
洋葱模型的特点是中间件的执行分为两个阶段:
- 入栈阶段:当请求到达时,中间件按照它们在应用中注册的顺序依次执行。每个中间件都有机会处理请求,如果它不打算阻止请求的传递,它会调用
next()
函数,将控制权交给下一个中间件。 - 出栈阶段:一旦所有的中间件都通过
next()
调用完成入栈阶段的执行,控制流开始回溯,即从最内部的中间件开始向外部返回。在这个阶段,中间件可以处理响应或进行任何清理操作。
因此,每个中间件实际上有两次执行的机会:一次在请求到达时,一次在请求即将完成时。这种模型允许中间件在请求和响应之间添加额外的逻辑,例如日志记录、错误处理、身份验证、数据解析等。
下面是一个简单的 Koa 应用程序示例,展示如何使用中间件:
const Koa = require('koa')
const app = new Koa()
// ctx 代表整个上下文对象 context
const one = (ctx, next) => { // 中间件的执行顺序是洋葱模型
console.log('One1')
next()
console.log('One2')
}
const two = (ctx, next) => {
console.log('Two1')
next()
console.log('Two2')
}
const three = (ctx) => {
console.log('Three1')
console.log('Three2')
}
app.use(one)
app.use(two)
app.use(three)
app.listen(3000, () => {
console.log('server is running at port 3000')
})
运行结果:
这段 Koa 应用程序代码展示了洋葱模型在中间件执行中的应用。让我们逐层剖析这个洋葱模型是如何工作的:
-
加载中间件:
- 首先,定义了三个中间件函数:
one
、two
和three
。 - 然后,使用
app.use()
方法将这些中间件按顺序添加到应用程序中。这意味着请求将首先通过one
,然后是two
,最后是three
。
- 首先,定义了三个中间件函数:
-
入栈阶段:
- 当一个 HTTP 请求到达时,控制流开始于最外层的中间件
one
。 - 在
one
中,console.log('One1')
打印 "One1",然后调用next()
函数,将控制权传递给下一个中间件two
。 - 同样的过程发生在
two
中,打印 "Two1" 并调用next()
将控制权传递给three
。 three
不再调用next()
,因为它是最内层的中间件。在这里,console.log('Three1')
和console.log('Three2')
直接打印内容而不传递控制。
- 当一个 HTTP 请求到达时,控制流开始于最外层的中间件
-
出栈阶段:
- 一旦
three
完成其任务,控制流开始回溯,即从内向外执行。 - 控制返回到
two
,此时console.log('Two2')
打印 "Two2"。 - 然后控制返回到
one
,console.log('One2')
打印 "One2"。
- 一旦
上述过程可以用下图来形象的表示:
总结
总结来说洋葱模型
就是确保了中间件以预定的顺序执行,并且每个中间件都有机会在请求和响应过程中执行自己的逻辑。在这个过程中,中间件可以相互协作,形成一个复杂但有序的处理链。
以上便是我对洋葱模型的理解,希望对大家有所帮助,谢谢大家。
转载自:https://juejin.cn/post/7389955238059442203