两分钟搞懂从函数组合到中间件实现

简介: 很多JS框架中都会用到中间件,形成一个洋葱圈结构,这样可以很好的应付业务逻辑中的对于切面描述的需要。 经典案例比如Redux 中间件和Koa 中间件

很多JS框架中都会用到中间件,形成一个洋葱圈结构,这样可以很好的应付业务逻辑中的对于切面描述的需要。 经典案例比如Redux 中间件和Koa 中间件


1.无组合状态


async function fn1(next){
    console.log('fn1')
    console.log('end fn1')
}
async function fn2(next){
    console.log('fn2')
    console.log('end fn2')
}
function fn3(next){
    console.log('fn3')
}
fn3(fn2(fn1()))


这个其实不能叫做组合 只是程序先运行最内层的表达式 然后向外运行 实际上这个执行顺序就是 fn1 -> fn2 -> fn3 执行结果如下:


fn1
end fn1
fn2
end fn2
fn3


当然这个里面你即使写await执行顺序也没有什么变化


(async () => {
    await fn3(await fn2(await fn1()))
})()


2.两个函数的组合


下面我们通过参数传递的方式把两个函数组合成一个函数。


async function fn1(next){
    console.log('fn1')
    next && await next()
    console.log('end fn1')
}
async function fn2(next){
    console.log('fn2')
    next && await next()
    console.log('end fn2')
}
fn2(fn1)


执行结果如下


fn2
fn1
end fn1
end fn2


3 多个函数的组合


影响多个函数不能串行的原因是 fn2的中不能返回函数结果。 解决这个问题的方法是不要函数的运行结果而是将函数科里化后返回


async function fn1(next){
    console.log('fn1')
    next && await next()
    console.log('end fn1')
}
async function fn2(next){
    console.log('fn2')
    next && await next()
    console.log('end fn2')
}
async function fn3(next){
    console.log('fn3')
    next && await next()
    console.log('fn3')
}
async function fn4(next){
    console.log('fn4')
    next && await next()
    console.log('fn4')
}
fn1(() => fn2(() => fn3(fn4)))


看一下执行结果


fn1
fn2
fn3
fn4
fn4
fn3
end fn2
end fn1


4.通用异步Compose函数


最后我们将这个操作写成一个通用函数


const compose = (...args) =>  {
    [first,...others] = args.reverse()
    let ret = first
    others.forEach(fn => {
        let retOld = ret
        ret = () => fn(retOld)
    })
    return ret
}
compose(fn1,fn2,fn3,fn4)()


相关文章
|
消息中间件 JSON 中间件
你用Go写过中间件吗?带你用Go实现【操作日志中间件】
管理后台所有修改,添加,删除的操作都要记录;操作日志的统计不影响主程序的性能
839 82
你用Go写过中间件吗?带你用Go实现【操作日志中间件】
|
中间件 uml
阿里中间件seata源码剖析六:TCC模式中2阶段提交实现
阿里中间件seata源码剖析六:TCC模式中2阶段提交实现
622 93
阿里中间件seata源码剖析六:TCC模式中2阶段提交实现
|
中间件 程序员 Go
你用Go写过中间件吗?带你用Gin实现【用户角色权限管理中间件】
管理后台有超管权限,超管拥有所有权限;普通管理员可以设置角色,角色单选;角色可以赋予多个权限,权限多选;这样我们就实现了对普通管理员的角色和权限的灵活管理
734 92
你用Go写过中间件吗?带你用Gin实现【用户角色权限管理中间件】
|
中间件 Python
Python编程:Django中间件实现登陆验证
Python编程:Django中间件实现登陆验证
308 52
Python编程:Django中间件实现登陆验证
|
中间件 Java Spring
从-1开始实现一个中间件
别人都写从0开始实现xxx,我先从-1开始就显得更牛逼一些。 今天,先开个头,来教大家怎么实现一个中间件。
300 52
从-1开始实现一个中间件
|
编解码 运维 监控
电商直播平台如何借助容器与中间件实现研发效率提升100%?
经过实际场景验证及用户的综合评估,电商直播平台借助全面的云原生容器化能力和中间件产品能力,大幅提升开发部署运维效率达50%~100%,极大地提升了用户体验,为业务持续发展打下了坚实的基础。
7458 70
电商直播平台如何借助容器与中间件实现研发效率提升100%?
|
存储 JavaScript NoSQL
SpringBoot2 整合MinIO中间件,实现文件便捷管理
MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。
925 58
SpringBoot2 整合MinIO中间件,实现文件便捷管理
|
存储 分布式计算 监控
阿里云互联网中间件:让企业实现业务云化持续创新|学习笔记
快速学习 阿里云互联网中间件:让企业实现业务云化持续创新
356 71
|
Web App开发 消息中间件 中间件
[.NET领域驱动设计实战系列]专题七:DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能
原文:[.NET领域驱动设计实战系列]专题七:DDD实践案例:引入事件驱动与中间件机制来实现后台管理功能 一、引言  在当前的电子商务平台中,用户下完订单之后,然后店家会在后台看到客户下的订单,然后店家可以对客户的订单进行发货操作。
1533 74

热门文章

最新文章