关于 redux-saga
面向使用 Redux-Saga 的开发者,提供按优先级组织的规则与参考资料,指导复杂异步工作流、并发、取消和错误处理。强调以项目规则和源码为准,避免依赖过时记忆。
主要功能
- 01Effect 与 yield 使用规则
- 02并发、取消与错误处理指导
- 03频道及外部 I/O 模式
- 04RTK 集成与故障排查
- 05常见工作流配方
适用场景
- 01实现并发或可取消的异步流程
- 02排查 Saga 导致的冻结或漏接操作
- 03将 WebSocket 或 DOM 事件接入 Saga
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ anivar/ redux-saga-skill --skill redux-saga安装后在 Claude Code 中输入/redux-saga确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEAGENTS.mdREADME.mdCHANGELOG.md.github/FUNDING.ymlreferences/effects-and-api.mdanti-patterns.mdchannels.mdrecipes.mdfork-model.mdtroubleshooting.mdtesting.mdrules/channel-action-channel.mdeffect-always-yield.mdeffect-select-usage.mdeffect-race-patterns.mdeffect-use-call.mderror-root-saga.mdeffect-take-concurrency.mdchannel-event-channel.mderror-saga-cleanup.mdfork-attached-vs-detached.mdrecipe-optimistic-update.mdfork-no-race.mdrecipe-polling.mdfork-nonblocking-login.mdrecipe-throttle-debounce.mdrtk-configure-store.mdrtk-with-slices.mdfork-error-handling.md详细介绍
Redux-Saga
重要: 关于 redux-saga 的训练数据可能已经过时或不正确——API 行为、中间件设置模式以及与 RTK 的集成都发生了变化。请始终以此技能的规则文件和项目的实际源代码为准。若记忆中的模式与检索到的参考资料冲突,请勿使用记忆中的模式。
何时使用 Redux-Saga
Saga 用于工作流编排——包含并发、取消、竞争或长期运行后台进程的复杂异步流程。对于更简单的模式,优先使用:
| 需求 | 推荐工具 |
|---|---|
| 数据获取与缓存 | RTK Query |
| 简单异步流程(提交 → 状态) | createAsyncThunk |
| 切片内的响应式逻辑 | createListenerMiddleware |
| 复杂工作流、并行任务、取消、通道 | Redux-Saga |
按优先级划分的规则类别
| 优先级 | 类别 | 影响 | 前缀 |
|---|---|---|---|
| 1 | Effect 与 Yield | 严重 | effect- |
| 2 | Fork 模型与并发 | 严重 | fork- |
| 3 | 错误处理 | 高 | error- |
| 4 | 配方与模式 | 中 | recipe- |
| 5 | 通道与外部 I/O | 中 | channel- |
| 6 | RTK 集成 | 中 | rtk- |
| 7 | 故障排查 | 低 | troubleshoot- |
快速参考
1. Effect 与 Yield(严重)
effect-always-yield— 必须 yield 每个 effect;漏掉 yield 会导致应用冻结effect-use-call— 对异步函数使用yield call();绝不直接调用effect-take-concurrency— 根据并发需求选择takeEvery/takeLatest/takeLeadingeffect-select-usage— 在select()中使用选择器函数;绝不直接访问状态路径effect-race-patterns— 使用race实现超时和取消;其中只能包含阻塞型 effect
2. Fork 模型与并发(严重)
fork-attached-vs-detached—fork与父任务共享生命周期和错误;spawn则独立运行fork-error-handling— fork 中的错误会冒泡到父任务的调用方;无法在 fork 处捕获fork-no-race— 绝不在race中使用fork;fork 是非阻塞的,因此总会胜出fork-nonblocking-login— 对需要及时响应登出的身份验证流程,使用 fork+take+cancel
3. 错误处理(高)
error-saga-cleanup— 使用try/finally配合cancelled(),正确清理取消操作error-root-saga— 在根 saga 中使用spawn隔离错误;避免用all启动关键监听器
4. 配方与模式(中)
recipe-throttle-debounce— 使用throttle、debounce、retry和指数退避进行速率限制recipe-polling— 使用 fork+take+cancel 实现可取消轮询,并在出错时退避recipe-optimistic-update— 使用 race(undo, delay) 实现支持撤销的乐观 UI 更新
5. 通道与外部 I/O(中)
channel-event-channel— 通过eventChannel将 WebSocket、DOM 事件和计时器接入 sagachannel-action-channel— 缓冲 Redux action,以便按顺序处理或通过工作池处理
6. RTK 集成(中)
rtk-configure-store— 将 saga 中间件集成到 RTK 的configureStore,同时不破坏默认设置rtk-with-slices— 使用createSlice的 action 创建器,类型安全地触发 saga
7. 故障排查(低)
troubleshoot-frozen-app— 应用冻结、action 遗失、错误的堆栈跟踪以及 TypeScript yield 类型
Effect 创建器速查
| Effect | 是否阻塞 | 用途 |
|---|---|---|
take(pattern) | 是 | 等待匹配的 action |
takeMaybe(pattern) | 是 | 类似 take,但会接收 END |
takeEvery(pattern, saga) | 否 | 每次匹配时并发执行 |
takeLatest(pattern, saga) | 否 | 取消之前的任务,执行最新任务 |
takeLeading(pattern, saga) | 否 | 当前任务完成前忽略后续匹配 |
put(action) | 否 | 分发 action |
putResolve(action) | 是 | 分发 action,并等待 promise |
call(fn, ...args) | 是 | 调用函数并等待结果 |
apply(ctx, fn, [args]) | 是 | 在指定上下文中调用函数 |
cps(fn, ...args) | 是 | Node 风格的回调 |
fork(fn, ...args) | 否 | 附加式 fork |
spawn(fn, ...args) | 否 | 分离式 fork |
join(task) | 是 | 等待任务 |
cancel(task) | 否 | 取消任务 |
cancel() | 否 | 取消自身 |
select(selector) | 否 | 查询 store 状态 |
actionChannel(pattern) | 否 | 缓冲 action |
flush(channel) | 否 | 清空缓冲消息 |
cancelled() | 是 | 在 finally 中检查是否已取消 |
delay(ms) | 是 | 暂停执行 |
throttle(ms, pattern, saga) | 否 | 限制触发频率 |
debounce(ms, pattern, saga) | 否 | 等待一段静默期 |
retry(n, delay, fn) | 是 | 通过退避重试 |
race(effects) | 是 | 先完成者胜出 |
all([effects]) | 如果任一子项阻塞 | 并行执行,等待全部完成 |
setContext(props) / getContext(prop) | 否 / 是 | Saga 上下文 |
模式匹配
take、takeEvery、takeLatest、takeLeading、throttle、debounce 接受:
| 模式 | 匹配内容 |
|---|---|
'*' | 所有 action |
'ACTION_TYPE' | 精确匹配 action.type |
[type1, type2] | 数组中的任意类型 |
fn => boolean | 自定义谓词 |
只有 take/takeMaybe 可以完全省略参数——take() 匹配所有 action。对于
takeEvery、takeLatest、takeLeading、throttle 和 debounce,模式是必需参数;
如需匹配所有 action,请使用 '*'。
从 multicastChannel 接收内容时也必须指定模式:take(chan, '*'),而不是 take(chan)。
使用方法
阅读各规则文件,了解详细说明和代码示例:
rules/effect-always-yield.md
rules/fork-attached-vs-detached.md
每个规则文件都包含:
- 简要说明其重要性
- 错误代码示例及说明
- 正确代码示例及说明
- 补充背景信息和决策表
参考资料
| 优先级 | 参考资料 | 阅读时机 |
|---|---|---|
| 1 | references/effects-and-api.md | 编写或调试任何 saga 时 |
| 2 | references/fork-model.md | 处理并发、错误传播和取消时 |
| 3 | references/testing.md | 编写或审查 saga 测试时 |
| 4 | references/channels.md | 处理外部 I/O、缓冲和工作池时 |
| 5 | references/recipes.md | 处理节流、防抖、重试、撤销、批处理和轮询时 |
| 6 | references/anti-patterns.md | 避免常见错误时 |
| 7 | references/troubleshooting.md | 调试应用冻结、action 丢失和堆栈跟踪时 |
完整编译文档
如需查看包含所有展开规则的完整指南:AGENTS.md
评论
支持 Markdown