You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
createStore(reducer,preloadedState,enhancer)=>{if(typeofenhancer!=='undefined'){if(typeofenhancer!=='function'){thrownewError('Expected the enhancer to be a function.')}// 所以第三种直接传入applyMiddleware(logger1, logger2),效果是一样的。returnenhancer(createStore)(reducer,preloadedState)}}
redux基础
createStore
一个工厂函数传入reducer,创建store,返回几个函数,主要是dispatch,getState,subscribe,replaceReducer,以及结合rx这种发布订阅库的symbol($$observable)
combineReducers
把单个的reducer组合成一个大的reducer。其实就是返回一个新的reducer函数,去遍历执行所有的子reducer,并返回state。
bindActionCreators
把我们写的一个js中的好多ActionCreator 通过遍历搞的一个对象里,并返回。
applyMiddleware
一个三阶函数,是用来改写store的dispatch方法,并把所有的中间件都compose串联起来,通过改写dispatch,来实现redux功能的拓展。
compose
一个组合多个middleware的方法,通过reduceRight方法(同理也可以是reduce),把传进来的middleware串成一条链,也可以看成回调接回调,一个预处理的方法。
redux-middleware
我们从redux中applyMiddleware使用入口开始研究。
中间件
为什么中间件要定义成这种三阶的样子呢,当然是中间件的消费者(applyMiddleware)规定的。
先通过一个小栗子看一下middleware的使用。
通过applyMiddleware执行可以得到一个store,store再通过react-redux中的provider注入。此时得到的store就是被改造了dispatch的。通过图来形象的解释一下:
可以看出redux在事件或者某个函数调用后,执行action(可能是bindActionCreators处理后的),由于bindActionCreator会去调用dispatch,
dispatch内部会把currenReducer执行,并把监听者执行。实现view更新。
但是经过applyMiddleware的包装,store里面的被封装,在调动action之后,执行封装后的dispatch就会经过一系列的中间件处理,再去触发reducer。
然后我们再通过研究源码,看他是怎么实现的封装dispatch。
思路可以从通过applyMiddleware创建store一点一点的看。
compose还是比较重要的
compose执行
chain中都是已经预置middlewareAPI参数后的二阶函数。执行传入的参数都是 形参next。
通过执行compose(...chain)(store.dispatch),last是最后一个中间件,执行并传入 store.dispatch, 返回一个只剩一阶的(action) => {}, 不过已经预置了next参数,也就是store.dispatch
然后last(...args)返回的结果传入reduceRight的回调, 对应形参是composed。
f是rest的最后一项, 执行并把 composed 传入,等同于f形参中的next... 得到的结果也是一阶函数,预置的next是last(...args) ...
以此类推。这样,就形成了一个嵌套多层的语句。
类似于
logger1(logger2(store.dispatch)
,当然这只是一个比喻。只不过到第一个middleware的时候,是二阶函数传入next执行,得到一阶函数返回赋值给dispatch,这时的一阶函数已经变成了形似这样:
经过compose之后的dispatch执行
返回的store中dispatch被修改,执行store.dispatch的时候,也就是这个函数执行.
当执行到next(action)的时候,会调用已经预置的next函数,也就是第二个中间件的(action) => {},依次类推。直到最后一个中间件,他的next函数是store.dispatch函数,执行并把action传入。
执行完最后一个中间件的next(action),也就是初始的dispatch。next后面的代码再执行,再逆向把中间件走一遍,直到第一个中间件执行完毕。
就会出现这种效果
用图形象点就是
这样redux middleware的执行流程就搞清楚了。
应用applyMiddleware的方式
createStore源码中有一个判断,
第一种先compose同理。一个参数的时候会返回applyMiddleware,变形之后也是一样的。
enhancer的用法很多种,不仅仅是applyMiddleware,比如Redux-Devtools, 都是利用了compose函数。自定义开发一些拓展功能还是很强大的...
redux里的compose是处理三阶函数的,恰巧createStore, applyMiddleware都是三阶函数,都可以通过compose串联起来。不禁感叹函数式编程思维的强大啊。
应用异步action
actionCreator之前都是返回一个
{type: 'UPDATE', text: 'aaa'}
这样的简单对象。通过thunk中间件,可以处理返回function的情况。express中的middleware
用法
每次访问这个app应用的时候,都会执行
模拟
假总结
现在web的中间件概念,都区别于最早严格意义上的中间件,其实我们现在的很多编程思想都是借鉴的先驱提出的一些东西。JAVA中类似的是AOP,即面向切面编程,以补充OOP(面向对象)多个对象公用某些方法时造成的耦合。
目前js中见到的中间件思想用法都是差不多的,只有调用next,程序才会继续往下执行,没有next,可以抛出异常等。只不过redux使用的函数式编程思想,用法偏函数式一些。
demo代码我会放到middleware-demo目录里,可以clone下来操作一番。链接
先到这,下次衍生就是函数式编程了。
The text was updated successfully, but these errors were encountered: