Redux middleware处理多action时并发派发新action的运行机制疑问
Redux 中间件并发派发 action 的行为说明
核心结论
- 中间件的同步执行逻辑是串行阻塞的,前一个 action 的同步处理流程没走完,新 action 不会开始处理
- 中间件里的异步逻辑是并行运行的,不需要等前一个 action 的异步回调完成,新 action 就可以进入处理流程
- 所有最终派发给 reducer 的普通 action(纯对象类型)永远是串行执行的,同一时间只会有一个 action 在修改 state,不会出现竞态问题
具体场景解释
场景1:前一个 action 只有同步处理逻辑
如果中间件处理 action 时没有异步操作,整个处理流程(中间件链路执行 → 进入 reducer 更新 state)是同步阻塞的。必须等前一个 action 的完整流程走完,新派发的 action 才会开始执行。
举个例子,你派发两个普通的同步 action:
dispatch({ type: 'UPDATE_COUNT', payload: 1 }) dispatch({ type: 'UPDATE_COUNT', payload: 2 })
这两个 action 会按先后顺序依次走完中间件、reducer,最终 state 的 count 会先加 1 再加 2,结果完全可预测。
场景2:前一个 action 包含异步处理逻辑
如果中间件处理 action 时发起了异步操作(比如接口请求、定时器),中间件只会同步执行到异步逻辑触发的位置,不会等待异步回调返回,直接交回控制权。这时候新派发的 action 会立刻进入中间件链路开始处理,两个 action 的异步逻辑会并行运行。
拿最常用的 redux-thunk 举个例子:
// 异步action1:获取用户信息 const fetchUser = () => async (dispatch) => { dispatch({ type: 'FETCH_USER_START' }) // 异步请求触发后,thunk中间件不会等待结果返回 const userRes = await fetch('/api/user') dispatch({ type: 'FETCH_USER_SUCCESS', payload: userRes.data }) } // 异步action2:获取列表数据 const fetchList = () => async (dispatch) => { dispatch({ type: 'FETCH_LIST_START' }) const listRes = await fetch('/api/list') dispatch({ type: 'FETCH_LIST_SUCCESS', payload: listRes.data }) } // 连续派发两个异步action dispatch(fetchUser()) dispatch(fetchList())
执行顺序如下:
- 第一个 dispatch 进入 thunk 中间件,执行 fetchUser 的函数体,同步派发
FETCH_USER_START,走到await fetch时退出本次 dispatch 的同步流程 - 立刻执行第二个 dispatch,进入 thunk 中间件执行 fetchList 的函数体,同步派发
FETCH_LIST_START,走到await fetch时退出本次同步流程 - 两个接口请求并行执行,哪个先返回,就先派发对应的 SUCCESS action 进入 reducer 更新 state
注意:即使两个异步请求同时返回,他们派发的 SUCCESS action 也会按调用顺序串行进入 reducer,不会出现同时修改 state 的情况,Redux 本身的 dispatch 机制保证了 reducer 的执行永远是单线程串行的,避免了竞态问题。
内容的提问来源于stack exchange,提问作者Bhavya Bhatt
相关产品推荐
相关产品推荐

