redux-saga根saga中All effect与Fork effect的适用场景对比
redux-saga根文件中all与fork方案的适用场景
rootSaga里两种常见写法的核心差异是错误传播逻辑和执行时序的不同,具体适用场景如下:
all 包裹并行fork的适用场景
- 适用中小型项目,所有业务saga需要在应用初始化时一次性全部启动,且业务之间强关联、某一个saga初始化失败则整体业务不可用的场景。
all会等待所有内部Effect执行完成后才会继续rootSaga后续逻辑,若其中任意一个Effect抛出未捕获错误,会直接终止所有并行的saga和整个rootSaga,方便统一做全局错误降级。 - 不需要动态增删saga、不需要对单个saga做独立生命周期控制的场景,这种写法结构更加清晰易维护。
示例代码:
export default function* rootSaga() { // 所有saga并行启动,任意一个报错全部终止 yield all([ fork(userSaga), fork(orderSaga), fork(goodsSaga) ]) }
逐个fork的适用场景
- 适用大型项目,需要做saga按需加载、热更新的场景,逐个fork的方式不会阻断rootSaga后续逻辑执行,可以在路由切换、模块加载时动态fork对应模块的saga,降低应用初始化性能开销。
- 各业务saga独立性高,某一个saga启动失败不需要影响其他正常业务运行的场景,单个fork的saga抛出错误不会终止其他已经启动的saga,也不会阻断rootSaga的后续执行。
- 需要对单个saga做精细化生命周期控制的场景,fork会返回task实例,你可以存储该实例,在需要的时候主动调用
cancel方法终止对应saga,适合临时挂载的监听类saga等场景。
示例代码:
export default function* rootSaga() { // 核心公共saga先启动 yield fork(publicSaga) // 监听路由切换事件,动态加载对应模块saga yield takeEvery('ROUTE_CHANGE', function* (action) { const moduleSaga = yield import(`./sagas/${action.payload.routeName}`) yield fork(moduleSaga.default) }) }
补充说明:实际项目中两种方案通常结合使用,将强关联的核心saga用
all包裹统一启动,独立业务/动态加载的saga用单独fork的方式处理即可。
内容的提问来源于stack exchange,提问作者Gourav Saini
相关产品推荐
相关产品推荐

