纵观 redux 的实现,函数式编程体现的淋漓尽致,中间件形式 store => next => action => { xx } 是函数柯里化作用的灵活体现,将多参数化为单参数,可以用于提前固定 store 参数,得到形式更加明确的 dispatch => dispatch,使得 compose得以发挥作用。
总结
总体而言,express 和 koa 的实现很类似,都是next 方法传递进行递归调用,只不过 koa 是promise 形式。redux 相较前两者有些许不同,先通过递归向外覆写,形成执行时递归向里调用。
总结一下三者关键异同点(不仅限于中间件):
实例创建: express 使用工厂方法, koa是类
koa 实现的语法更高级,使用ES6,支持generator(async await)
koa 没有内置router, 增加了 ctx 全局对象,整体代码更简洁,使用更方便。
koa 中间件的递归为 promise形式,express 使用while 循环加 next 尾递归
我更喜欢 redux 的实现,柯里化中间件形式,更简洁灵活,函数式编程体现的更明显
redux 以 dispatch 覆写的方式进行中间件增强
最后再次附上 模拟示例源码 以供学习参考,喜欢的欢迎star, fork!
回答一个问题
有人说,express 中也可以用 async function 作为中间件用于异步处理? 其实是不可以的,因为 express 的中间件执行是同步的 while 循环,当中间件中同时包含 普通函数 和 async 函数 时,执行顺序会打乱,先看这样一个例子:
function a() { console.log('a') } async function b() { console.log('b') await 1 console.log('c') await 2 console.log('d') } function f() { a() b() console.log('f') }
这里的输出是 'a' > 'b' > 'f' > 'c'
在普通函数中直接调用async函数, async 函数会同步执行到第一个 await 后的代码,然后就立即返回一个promise, 等到内部所有 await 的异步完成,整个async函数执行完,promise 才会resolve掉.
所以,通过上述分析 express中间件实现, 如果用async函数做中间件,内部用await做异步处理,那么后面的中间件会先执行,等到 await 后再次调用 next 索引就会超出!,大家可以自己在这里 express async 打开注释,自己尝试一下。