正如您在middleware example 中看到的,有多个中间件项可以创建管道:
rafScheduler -> timeoutScheduler -> thunk -> vanillaPromise -> etc...
在到达基本 reducer 或被其中一个中间件项拦截之前,动作会遍历所有中间件项。每个中间件项可以决定通过使用next() 将操作移动到链中的下一个中间件。但是,有时我们希望动作从一开始就在链中传播。
例如,使用 redux thunk,我们调度了一个异步操作,该操作将由 thunk 中间件处理。当异步调用成功时,异步操作将调度另一个操作。此操作应使用rafScheduler 中间件重新开始。
如果调度会像下一个一样工作,它将转而前往vanillaPromise 中间件。为了解决这个问题,dispatch(action),无论在哪里调用,总是从一开始就遍历链。
要创建此行为 applyMiddleware() 运行中间件 store => next => action 方法,将 middlewareAPI api 传递给 store 参数,传递并覆盖 store.dispatch,新的调度是 @987654322 @中间件。这就是魔法发生的地方 - 新的调度是中间件方法链,每个调用 next 时调用它之后的一个(next = 下一个中间件方法),最后一个 next() 是旧的 store.dispatch调用基本减速器:
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
var store = createStore(reducer, preloadedState, enhancer)
var dispatch = store.dispatch // this is the original dispatch
var chain = []
/*** this the store param of the middleware ***/
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
/*** store param is applied to old middlewares to create the chain ***/
chain = middlewares.map(middleware => middleware(middlewareAPI))
/*** The chain is composed. For all methods in the chain, but the last, next() is the middleware method after it in the chain, the last next is store.dispatch ***/
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch // the new dispatch is returned instead of the old
}
}
}