我知道middleware的代码是类似这样的:
export default function thunkMiddleware({ dispatch, getState }) {
return next => action => {
if (typeof action === 'function') {
return action(dispatch, getState);
}
return next(action);
};
}
applyMiddleware的代码是这样的:
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, initialState, enhancer) => {
var store = createStore(reducer, initialState, enhancer)
var dispatch = store.dispatch
var chain = []
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
// 将middleware初始化,些时chain里是Array<next=>action=>doSomething>
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
compose的实现:
export default function compose(...funcs) {
return (...args) => {
if (funcs.length === 0) {
return args[0]
}
const last = funcs[funcs.length - 1]
const rest = funcs.slice(0, -1)
return rest.reduceRight((composed, f) => f(composed), last(...args))
}
}
接收一堆参数fns,返回另一个函数。在这个函数里,将参数中的函数逐个从右到左执行,上一个执行的结果将做为下一个执行的参数。
即compose(f, g, h)(100)相当于f(g(h(100))). 而对于上面的
dispatch = compose(...chain)(store.dispatch)
最后会是默认的dispatch一个action(action)。
假如有很多个middleware,那怎么把参数从一个middleware传到下一个middleware?
比如说redux-thunk,它的代码是这样的:
export default function thunkMiddleware({ dispatch, getState }) {
return next => action =>
typeof action === 'function' ?
action(dispatch, getState) :
next(action);
}
下面的一个案例:
var asyncSayActionCreator = function (message) {
return function (dispatch) {
setTimeout(function () {
dispatch({
type: 'SAY',
message
})
}, 2000)
}
}
但我dispatch(asyncSayActionCreator('hello world'));
可以看到它最后是直接
dispatch({
type: 'SAY',
message
})
直接dispatch了(这个dispatch是未经改造的),又没有返回其它的参数给其它的middleware,那其它的middleware完全没起作用?即使其它的middleware也可以对function类型的action处理?回看redux-thunk的代码,如果action是function,它完全不理它下面的middleware了啊..........
求解答.......
问题太长了,没人会看吧。