JS中间件设计模式:原理、洋葱模型与实现解析
本文深入探讨JavaScript中间件的设计模式,以Redux和Koa为例解析其核心思想。通过对比有next和无next的两种实现,揭示中间件对处理逻辑的改造机制及洋葱模型执行顺序。文章提供简化代码示例,帮助开发者理解中间件的本质与通用实现逻辑。
本文通过具体实例解析JavaScript中的中间件设计模式,旨在为读者提供参考。
中间件设计思想概述
中间件作为一种辅助处理机制,在技术生态中应用广泛,例如Express、Redux和Koa均采用了该模式。本文将结合具体使用场景,深入探讨中间件的设计思想及其通用实现方式。
参考Redux中间件的实现思路,我们先看一个具体示例。
Redux风格中间件与洋葱模型
function fn2(next){
console.log('执行2,返回改造的next之前')
return action => {
console.log('执行2')
next(action)
}
}
function fn3(next){
console.log('执行3,返回改造的next之前')
return action => {
console.log('执行3')
next(action)
}
}
function fn1(next){
console.log('执行1,返回改造的next之前')
return action => {
console.log('执行1')
getData().then( data => {
next(action)
})
}
}
function getData(){
return new Promise(resolve => {
setTimeout( () => {
resolve(true)
},3000)
})
}
const next = (action) => {
console.log('action',action)
}
// compose([fn1,fn2,fn3])(next)
const mm = [fn1,fn2,fn3].reduce(function(a,b,currentIndex,arr){
console.log("a",a)
console.log("b",b)
return function(...args){
console.log('args',[...args][0].toString())
return a(b(...args))
}
})(next)(1)
运行结果展示了类似“洋葱圈”模型的执行流程,但其特点是从内层向外层执行,再由外层向里层返回。
执行3,返回改造的next之前 args action => { console.log('执行3') next(action) } 执行2,返回改造的next之前 执行1,返回改造的next之前 执行1 执行2 执行3 action 1
接下来对上述实例进行简化处理:
简化版中间件实现
function fn2(action){
console.log('执行2,返回改造的next之前')
action+2
}
function fn3(action){
console.log('执行3,返回改造的next之前')
action+1
}
function fn1(action){
console.log('执行1,返回改造的next之前')
return action+1
}
function getData(){
return new Promise(resolve => {
setTimeout( () => {
resolve(true)
},3000)
})
}
const next = (action) => {
console.log('action',action)
}
// compose([fn1,fn2,fn3])(next)
const mm = [fn1,fn2,fn3].reduce(function(a,b,currentIndex,arr){
console.log("a",a)
console.log("b",b)
return function(...args){
console.log('args',[...args])
return a(b(...args))
}
})(1)
此时的中间件仅包含单一层的处理逻辑,未传递初始处理逻辑,因此中间件是单一的。运行结果如下:
args [ 1 ] 执行3,返回改造的next之前 args [ undefined ] 执行2,返回改造的next之前 执行1,返回改造的next之前
中间件的本质与分类
抽离通用逻辑并深入本质,中间件的核心作用是对最初的处理逻辑函数进行改造;若不存在初始处理逻辑,则仅执行自身的逻辑。
第一种情况:仅包含自身逻辑的单一中间件。
第二种情况:包含初始处理逻辑函数next的中间件,需要接收next参数,并返回一个新的next'。
感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。
更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。
Three.js 使用 TransformControls 实现模型拖拽交互
2026-11-01 02:14:15
JS开发接入 DeepSeek 实现 AI 智能问诊
2026-10-31 18:58:41
uniapp微信小程序集成xr-frame加载3D模型完整指南
2026-10-31 14:27:13
Wiki.js 支持哪些编辑器?Markdown 与可视化编辑切换指南
2026-10-30 19:14:38
Java与JavaScript的核心差异:运行环境与执行机制对比
2026-10-30 19:01:40
