Redux-Saga 的优雅使用

阅读时长 9 分钟读完

作为前端开发,我们在处理复杂业务逻辑时往往会遇到很多异步操作,而在 Redux 应用中,我们可以利用 Redux-Saga 来处理这些异步操作。Redux-Saga 基于 Generator 函数实现,使得异步流程非常优雅,易于理解和维护。本文将介绍 Redux-Saga 的用法以及一些优雅的使用技巧,帮助读者更好的使用 Redux-Saga。

什么是 Redux-Saga

Redux-Saga 是一个用于管理应用程序副作用的库,如异步调用、监视并响应 Redux 状态等。它是一个基于 Generator 函数的方案,允许将异步操作表达为简单的同步代码,如果您不熟悉 Generator 函数,可以先了解一下。Redux-Saga 提供了一种简单的方法来在 Redux 应用程序中创建可扩展和易于维护的异步流程。

Redux-Saga 的使用

安装和配置

首先,我们需要安装 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,putdispatch 作用相同。

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 提供了 catchfinallycancelled 三个函数来处理错误。下面是一个例子:

-- -------------------- ---- -------
--------- ------------ -
  --- -
    ----- ---- - ----- ------------
    ----- ----- ----- ------------ -------- ---- ---
  - ----- ------- -
    --------------------- -------
  - ------- -
    ------------------- ---- ----------
  -

  -- ------ ------------
    ------------------- ---- ------------
-

--------- ------------- -
  ----- ------ -
    ----- --------------------- ------------
  -
-

串行执行

在 Saga 中,我们可以使用 call 函数来实现函数调用的串行执行。下面是一个例子:

-- -------------------- ---- -------
--------- ------------------ -
  ----- --- - --------------------------------------------------------
  ----- -------- - ----- ----------- -----
  ------ ----- ----------------
-

--------- ------------ -
  --- -
    ----- ------- ------ - ----- -----
      --------------- ---
      --------------- --
    ---
    ----- ----- ----- ------------ -------- ------- ------ ---
  - ----- ------- -
    --------------------- -------
  -
-

--------- ------------- -
  ----- -------------------- ------------
-

上面例子中,我们使用 all 函数同时执行两个 fetchData 函数,等它们都执行完后,再执行后续的代码。

并行执行

与串行执行不同,我们可以使用 fork 函数来实现函数的并行执行。fork 函数将启动一个子进程,使 Saga 可以并行运行多个任务。由于我们的应用程序在后台执行此操作,因此不必等待结果,这样就不会阻止 UI 的渲染过程。下面是一个例子:

-- -------------------- ---- -------
--------- ------------------- -
  ----- - ------ - - --------
  ----- -------- ------- ------ - ----- -----
    ----------------- --------
    ----------------- --------
    ---------------- -------
  ---
  ----- ----- ----- ------------------- -------- - ------- ------- ----- - ---
-

--------- ------------- -
  ----- ---------------------------- --------- -------- -
    ----- ---------------- ----------------
  ---
-

在上面的代码中,我们使用 all 函数同时执行多个 fetchData 函数,并在它们都执行完后,再将它们的结果封装在一个 action 中一起 dispatch 出去。

结论

Redux-Saga 是一个非常优雅的异步处理库,在处理复杂业务逻辑时更加易于理解和维护。通过掌握 Saga 的工作原理和用法,我们可以更加高效地处理复杂的异步操作。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6750c6a8050cf9039c1675b3

纠错
反馈