作为前端开发,我们在处理复杂业务逻辑时往往会遇到很多异步操作,而在 Redux 应用中,我们可以利用 Redux-Saga 来处理这些异步操作。Redux-Saga 基于 Generator 函数实现,使得异步流程非常优雅,易于理解和维护。本文将介绍 Redux-Saga 的用法以及一些优雅的使用技巧,帮助读者更好的使用 Redux-Saga。
什么是 Redux-Saga
Redux-Saga 是一个用于管理应用程序副作用的库,如异步调用、监视并响应 Redux 状态等。它是一个基于 Generator 函数的方案,允许将异步操作表达为简单的同步代码,如果您不熟悉 Generator 函数,可以先了解一下。Redux-Saga 提供了一种简单的方法来在 Redux 应用程序中创建可扩展和易于维护的异步流程。
Redux-Saga 的使用
安装和配置
首先,我们需要安装 Redux-Saga:
npm install --save redux-saga
接着,在 Redux 应用程序中将其配置为中间件。Redux-Saga 通过 createSagaMiddleware
来创建中间件,将其应用到 Redux store 上,如下所示:
-- -------------------- ---- ------- ------ -------------------- ---- ------------- ------ ----------- ---- ------------- ------ -------- ---- ---------- ----- -------------- - ----------------------- ----- ----- - ------------ ------------ ------------------------------- -- -----------------------------
Saga 的结构
一个 Redux-Saga 由多个 Generator 函数组成,每个 Generator 函数都是一个 Saga 独立的异步流程,它可以是:
watcher Saga
- 监听某些 action,并在它们被 dispatch 时触发一个相应的 worker Saga。worker Saga
- 执行实际的任务。root Saga
- 启动其他 Saga。
下面是一个简单的 Saga 形式:
-- -------------------- ---- ------- ------ - ---- --------- - ---- --------------------- ------ - ---------- ----------- - ---- -------------- --------- ------------ - --- - ----- ---- - ----- ------------ ----- ----- ----- ------------ -------- ---- --- - ----- ------- - --------------------- ------- - - --------- ------------- - ----- -------------------- ------------ - ------ ------- --------- ---------- - ----- --------------------- -
我们将在下面的章节中更详细地讨论这些函数的作用。
Effect 和 Effect Creator
Saga 中的每个 yield 都会返回 Effect 对象,它是对异步操作的描述。Effect Creator 是用来创建 Effect 对象的函数,常用的 Effect Creator 如下:
put(action)
将一个 action 发送给 store,正常情况下,我们使用 dispatch
来给 store 发送 action,put
与 dispatch
作用相同。
call(fn, ...args)
调用普通函数,返回一个 Effect 对象,Saga 会暂停执行,直到函数执行结束,再执行下一行代码。yield call(someFunction, arg1, arg2)
会调用 someFunction(arg1, arg2)
。
take(pattern)
暂停 Saga,直到一个匹配 pattern 的 action 被 dispatch,实际上是通过 Generator 的方式来处理 Redux store 的 action。
takeEvery(pattern, saga)
监听匹配 pattern 的每个 action,并在触发时运行 saga,取代 Redux 中的 action。
takeLatest(pattern, saga)
监听匹配 pattern 的每个 action,并在触发时运行 saga,但如果在上一个操作执行完之前,又有新的匹配 pattern 的 action 被触发,那么之前的 Saga 将自动取消。
select(selector, ...args)
从 store 中取出选中的 state 片段,并传递给指定的 selector 函数。yield select(getData)
会执行 selector 函数 getData
,并将 store 中 getData()
返回的结果值作为 Effect 对象返回。
all(effects)
并发运行所有的 Effects,并等待它们都完成。等待期间,Saga 将暂停执行。
race(effects)
运行 Effects 数组中的每个 Effect,但一旦有一个 Effect 完成了,其他 Effects 将被取消。
Redux-Saga 提供了很多优雅的使用技巧,可以让我们更好地处理复杂的异步操作。
停止 Saga
我们可以使用 cancel
Effect 来停止正在运行的 Saga。当有一个新的匹配 pattern 的 action 时,我们就可以使用 cancel
效果来停止前一个 Saga 执行代码。下面是一个例子:
-- -------------------- ---- ------- --------- ------------ - --- ----- --- - ----- ------ - ----- - ------- - - ----- ---------------- -- ------ - ----- ------------- - ---- - ----- --------------- --------- ----- ----- ----- ----------------------- ------- --- - - ------- - -- ------ ------------ - ----------------------- ------------ - - -
错误处理
Saga 可以通过 try ... catch
语句捕获错误以及任何被取消的 Saga。Saga 提供了 catch
、finally
和 cancelled
三个函数来处理错误。下面是一个例子:
-- -------------------- ---- ------- --------- ------------ - --- - ----- ---- - ----- ------------ ----- ----- ----- ------------ -------- ---- --- - ----- ------- - --------------------- ------- - ------- - ------------------- ---- ---------- - -- ------ ------------ ------------------- ---- ------------ - --------- ------------- - ----- ------ - ----- --------------------- ------------ - -
串行执行
在 Saga 中,我们可以使用 call
函数来实现函数调用的串行执行。下面是一个例子:
-- -------------------- ---- ------- --------- ------------------ - ----- --- - -------------------------------------------------------- ----- -------- - ----- ----------- ----- ------ ----- ---------------- - --------- ------------ - --- - ----- ------- ------ - ----- ----- --------------- --- --------------- -- --- ----- ----- ----- ------------ -------- ------- ------ --- - ----- ------- - --------------------- ------- - - --------- ------------- - ----- -------------------- ------------ -
上面例子中,我们使用 all
函数同时执行两个 fetchData
函数,等它们都执行完后,再执行后续的代码。
并行执行
与串行执行不同,我们可以使用 fork
函数来实现函数的并行执行。fork
函数将启动一个子进程,使 Saga 可以并行运行多个任务。由于我们的应用程序在后台执行此操作,因此不必等待结果,这样就不会阻止 UI 的渲染过程。下面是一个例子:
-- -------------------- ---- ------- --------- ------------------- - ----- - ------ - - -------- ----- -------- ------- ------ - ----- ----- ----------------- -------- ----------------- -------- ---------------- ------- --- ----- ----- ----- ------------------- -------- - ------- ------- ----- - --- - --------- ------------- - ----- ---------------------------- --------- -------- - ----- ---------------- ---------------- --- -
在上面的代码中,我们使用 all
函数同时执行多个 fetchData
函数,并在它们都执行完后,再将它们的结果封装在一个 action 中一起 dispatch 出去。
结论
Redux-Saga 是一个非常优雅的异步处理库,在处理复杂业务逻辑时更加易于理解和维护。通过掌握 Saga 的工作原理和用法,我们可以更加高效地处理复杂的异步操作。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6750c6a8050cf9039c1675b3