Redux 中间件的执行顺序遵循洋葱模型,即中间件的注册顺序决定了它们的外层执行顺序,而内层逻辑(如异步回调)的执行顺序则相反。以下是详细解释:
1. 注册顺序决定外层执行顺序
当使用applyMiddleware
注册多个中间件时,它们的外层逻辑按注册顺序执行:
javascript
import { createStore, applyMiddleware } from 'redux';
import middleware1 from './middleware1';
import middleware2 from './middleware2';
import middleware3 from './middleware3';
const store = createStore(
rootReducer,
applyMiddleware(middleware1, middleware2, middleware3)
);
执行顺序:
dispatch(action)
→ middleware1
→ middleware2
→ middleware3
→ reducer
2. 中间件的结构与洋葱模型
每个中间件的结构是三层函数:
别再让才华被埋没,别再让github 项目蒙尘!github star 请点击
GitHub 在线专业服务直通车GitHub赋能精灵 - 艾米莉,立即加入这场席卷全球开发者的星光革命!若你有快速提升github Star github 加星数的需求,访问taimili.com还可解锁更多专属服务。现在转发邀请好友组队,在艾米莉加星平台解锁神秘流量加成,让我们携手点亮开源世界的璀璨星空,实现GitHub star项目涨星的无限可能!
javascript
const middleware = store => next => action => {
// 外层逻辑(按注册顺序执行)
const result = next(action); // 将action传递给下一个中间件
// 内层逻辑(按注册顺序的逆序执行)
return result;
};
洋葱模型图示:
plaintext
dispatch(action)
↓
middleware1 (外层)
↓
middleware2 (外层)
↓
middleware3 (外层)
↓
reducer
↓
middleware3 (内层)
↓
middleware2 (内层)
↓
middleware1 (内层)
↓
返回结果
3. 示例:日志中间件的执行顺序
假设有两个日志中间件:
javascript
const logger1 = store => next => action => {
console.log('Logger1: Before action');
const result = next(action);
console.log('Logger1: After action');
return result;
};
const logger2 = store => next => action => {
console.log('Logger2: Before action');
const result = next(action);
console.log('Logger2: After action');
return result;
};
注册顺序:
javascript
applyMiddleware(logger1, logger2);
执行结果:
plaintext
Logger1: Before action
Logger2: Before action
// reducer 执行
Logger2: After action
Logger1: After action
4. 异步中间件的执行顺序
对于异步中间件(如 Redux Thunk),异步回调的执行发生在内层逻辑:
javascript
const asyncMiddleware = store => next => action => {
console.log('Async: Before dispatch');
if (typeof action === 'function') {
// 异步逻辑(在内层执行)
return action(store.dispatch, store.getState);
}
const result = next(action);
console.log('Async: After dispatch');
return result;
};
如果注册顺序为:
javascript
applyMiddleware(asyncMiddleware, logger);
执行结果:
plaintext
Async: Before dispatch
Logger: Before action
// reducer 执行
Logger: After action
Async: After dispatch (如果action是普通对象)
5. 关键规则
- 外层逻辑按注册顺序执行:先注册的中间件先处理 action。
- 内层逻辑按逆序执行:最后注册的中间件的内层逻辑最先执行。
- next (action) 是分水岭:调用
next(action)
前的代码在外层,之后的代码在内层。
6. 最佳实践
- 顺序影响行为:中间件的注册顺序至关重要,例如:
- 日志中间件通常放在最后,以便捕获完整的 action 处理过程。
- 错误处理中间件应放在靠前位置,确保能捕获所有中间件的异常。
- 避免依赖顺序:设计中间件时应尽量独立,避免对特定顺序的强依赖。
总结
Redux 中间件的执行顺序遵循洋葱模型:
- 外层逻辑(
next(action)
之前)按注册顺序执行。 - 内层逻辑(
next(action)
之后)按注册顺序的逆序执行。 - 异步中间件的回调通常发生在内层逻辑中。
github star
理解这一顺序有助于合理安排中间件的注册位置,以及调试复杂的异步流程。