js实现applyMiddleWare
实现applyMiddleware的基本概念
在Redux中,applyMiddleware是一个用于增强store的功能的函数。它允许在dispatch action和到达reducer之间插入自定义逻辑。中间件可以用于日志记录、异步操作、错误处理等场景。
中间件的结构
一个Redux中间件通常是一个三层嵌套的函数,结构如下:
const middleware = store => next => action => {
// 中间件逻辑
return next(action);
}
实现applyMiddleware
以下是applyMiddleware的基本实现方式:
function applyMiddleware(...middlewares) {
return createStore => (...args) => {
const store = createStore(...args);
let dispatch = () => {
throw new Error('Dispatching while constructing your middleware is not allowed.');
};
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
};
const chain = middlewares.map(middleware => middleware(middlewareAPI));
dispatch = compose(...chain)(store.dispatch);
return {
...store,
dispatch
};
};
}
compose函数的实现
applyMiddleware依赖的compose函数可以将多个函数组合起来:

function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg;
}
if (funcs.length === 1) {
return funcs[0];
}
return funcs.reduce((a, b) => (...args) => a(b(...args)));
}
使用示例
创建一个日志中间件并使用applyMiddleware:
const logger = store => next => action => {
console.log('dispatching', action);
let result = next(action);
console.log('next state', store.getState());
return result;
};
const store = createStore(
rootReducer,
applyMiddleware(logger)
);
中间件的执行顺序
中间件的执行顺序与传入applyMiddleware的顺序有关。第一个中间件最先接收到原始dispatch,最后一个中间件最后执行。

异步中间件示例
Redux-thunk是一个常见的异步中间件实现:
const thunk = store => next => action => {
if (typeof action === 'function') {
return action(store.dispatch, store.getState);
}
return next(action);
};
注意事项
在中间件中不要直接修改action对象,应该返回一个新的action或直接传递原始action。避免在中间件构造阶段进行dispatch操作,这会导致错误。
测试中间件
测试中间件时,可以模拟store环境:
const testMiddleware = middleware => {
const store = {
getState: jest.fn(),
dispatch: jest.fn()
};
const next = jest.fn();
const action = { type: 'TEST' };
middleware(store)(next)(action);
return { store, next, action };
};






