Redux-Saga 是 Redux 中非常流行的解决方案之一,它可以让我们更好地管理应用程序中的副作用,如异步代码、时间延迟等。本文将介绍自己动手实现 Redux-Saga 的详细过程,并提供示例代码供读者学习。
什么是 Redux-Saga
Redux-Saga 是一个 Redux 中间件,它可以轻松地处理异步操作,例如 API 调用和 WebSocket 连接。它通过生成标准的 JavaScript Generator 函数来实现这一点,这些函数具有很高的可读性和可测试性。
在 Redux-Saga 中,saga 指的是一种特殊的 Generator 函数,用来处理 redux 中的副作用(即 Action)。
Redux-Saga 的主要特点:
- 通过了解类似于 Generator 的函数语法,简化了异步事务。
- 可使负责异步事务的代码更容易测试。
- 为复杂的场景提供了更高级别的抽象。
- 在处理异步操作方面提供了可靠的模式。
在 Redux-Saga 中,我们可以将异步操作从 reducer 中抽出来,并在 saga 中统一管理,这样可以使代码更加优雅和易于维护。
为了更好地理解 Redux-Saga 的原理和机制,我们在这里尝试自己动手实现一个简单的 Saga。
步骤一:定义一个 Saga
我们首先需要定义一个 Saga ,它是一个 Generator 函数,用来处理 redux 和副作用之间的交互。
function* helloSaga() { console.log('Hello Saga'); }
步骤二: 将 Saga 与 Store 关联
我们创建了 Saga ,现在需要将它与 Redux Store 关联起来,这需要使用 Redux 的 Middleware。
-- -------------------- ---- ------- ------ - ------------ --------------- - ---- -------- ------ -------------------- ---- ------------- ----- -------------- - ----------------------- ----- ----- - ------------ ------------ -------------------------------- -- ------------------------------
在上面的代码中,我们通过 createSagaMiddleware
函数创建了 Saga 中间件,并将中间件作为参数传递给 applyMiddleware
函数,这样就能够与 Store 关联起来了。我们还通过 run
方法给 Saga 中间件传递 helloSaga
方法,这样就能够启动 Saga 了。
步骤三:触发 Saga
现在,我们已经定义了 Saga 并将其与 Store 关联,但是我们还没有触发它。我们可以通过 dispatch 一个特定 Action 来触发它。
store.dispatch({ type: 'HELLO' });
这会触发 helloSaga
中第一个 yield
语句的输出。我们可以通过多次调用 store.dispatch
方法来触发其他 Saga 操作。
步骤四:在 Saga 中添加 Effects
目前,helloSaga
看起来并不像一个 Saga ,它只是一个简单的 Generator 函数。我们需要添加一些称为 Effects 的特殊指令,以便 Saga 函数能够处理副作用。
我们将创建一个 Saga ,用来处理一个 API 请求:
-- -------------------- ---- ------- ------ - ----- ---- --------- - ---- --------------------- ------ --- ---- -------- --------- ----------------- - --- - ----- ---- - ----- ------------------- ----------------------- ----- ----- ----- ----------------------- ----- ---- --- - ----- --- - ----- ----- ----- -------------------- -------- --------- --- - - --------- -------- - ----- --------------------------------- ----------- -
在上面的代码中,我们使用了三个 Effect: call
、put
和 takeEvery
。
call(fn, ...args)
: 该 Effect 调用fn
函数并传递args
参数。如果fn
返回 Promise 对象,则该 Effect 阻塞 Generator,直到 Promise 完成,然后将其解析为 Promise 的结果。put(action)
: 将 action 分派给Store
。takeEvery(pattern, saga, ...args)
: 监听Store
并在匹配pattern
的 Action 触发时执行saga
。
在上面的 Saga 中,我们监听了 USER_FETCH_REQUESTED
Action ,并在它触发时调用 fetchUser
函数。fetchUser
函数使用 call
Effect 调用 Api.fetchUser
函数并传递 action.payload.userId ,然后使用 put
Effect 将 USER_FETCH_SUCCEEEDED
和 USER_FETCH_FAILED
Action 分派给 Store
。
现在,我们创建了一个具有副作用和Effect 的 Saga 。
总结
在本文中,我们介绍了 Redux-Saga 的作用,以及如何用 Generator 函数实现一个简单的 Saga 。我们学习了如何将 Saga 与 Redux Store 关联起来,并如何使用 Effect 处理副作用。
学习了这个基础之后,我们就可以继续深入学习,使用 Redux-Saga 处理更复杂的场景,并且可以使代码更加优雅和清晰。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64cdac001519ea946c17a328