跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

JavaScript中Saga利用Generator管理复杂异步方案

Saga 模式通过 Generator 函数实现可读、可测试、可中断的异步流程管理,核心是 yield 暂停并返回 Effect 描述操作,由中间件执行;支持监听、取消、竞态处理与流程编排。 JavaScript 中的 Saga 模式通过 Generator 函数实现对复杂异步流程(如多步骤请求、错误恢复、并发控制、取消操作)的可读、可测试、可中断的管理。它不直接处理 Promise,而是把异步逻辑“暂停”在 yield 处,由中间件(如 redux-saga)接管执行与调度。 Generator 是 Saga 的核心执行载体 Generator 函数用 function* 声明,配合 yield 暂停执行,并返回一个迭代器对象。Saga 就是一系列被 yield 暂停的 Effect(如 call、put、take),它们本身不执行异步操作,只描述“要做什么”。 yield call(api.fetchUser, id) —— 描述“调用 fetchUser 并等待结果”,实际执行由 saga middleware 完成 yield take('USER_LOGIN_REQUEST') —— 描述“等待某个 action 被 dispatch”,挂起直到匹配 yield race({ login: call(loginApi), timeout: delay(5000) }) —— 描述“登录或超时,任一完成即结束” Saga 解决传统异步方案的痛点 对比 async/await 或纯 Promise 链,Saga 在以下场景更清晰可控: 使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件 如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Andr​​oid友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Andr​​oid应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更 下载 监听全局动作 :比如在任意时刻收到 LOGOUT,立即取消所有进行中的请求(通过 fork + cancel 实现) 多路分支与竞态处理 :用户快速切换 tab,前一个请求应自动取消,避免状态错乱(takeLatest 效果) 流程编排与重试 :登录失败后自动弹窗 → 等待用户点击重试 → 最多重试 3 次 → 失败则跳转错误页 测试友好 :Saga 函数返回纯对象序列(Effect),可逐条断言 yield 结果,无需 mock 时间或网络 一个典型可取消的登录 Saga 示例 下面是一个带加载、错误、取消逻辑的登录流程: 立即学习 “ Java免费学习笔记(深入) ”;
function* loginFlow() { while (true) { const { payload } = yield take('LOGIN_REQUEST'); const task = yield fork(authorize, payload); const action = yield take(['LOGIN_SUCCESS', 'LOGIN_FAILURE', 'LOGOUT']); if (action.type !== 'LOGIN_SUCCESS' && action.type !== 'LOGIN_FAILURE') { yield cancel(task); // 收到 LOGOUT,取消登录任务 } } }

function* authorize({ username, password }) { try { const token = yield call(api.login, { username, password }); yield put({ type: 'LOGIN_SUCCESS', token }); } catch (err) { yield put({ type: 'LOGIN_FAILURE', error: err.message }); } }

关键要点与注意事项 Saga 必须注册到 store(通过 applyMiddleware(createSagaMiddleware())),否则 yield 不会被拦截执行 所有异步副作用必须用 call / cps / fork 等 Effect 包裹,直接写 fetch() 不会暂停,也无法被取消 避免在 Saga 中直接修改 state 或调用 this.setState;所有状态变更应通过 put 发送 action 注意内存泄漏:fork 启动的子任务若未正确 cancel 或 done,可能持续监听或轮询

相关文章