使用 Saga 辅助函数

redux-saga 提供了一些辅助函数,用来在一些特定的 action 被发起到 Store 时派生任务。

这些辅助函数构建在低阶 API 之上。我们将会在高级概念一节看到这些函数是如何实现的。

第一个函数,takeEvery 是最常见的,它提供了类似 redux-thunk 的行为。

让我们演示一下常见的 AJAX 例子。每次点击 Fetch 按钮时,我们发起一个 FETCH_REQUESTED 的 action。
我们想通过启动一个任务从服务器获取一些数据,来处理这个 action。

首先我们创建一个将执行异步 action 的任务:

  1. import { call, put } from 'redux-saga/effects'
  2. export function* fetchData(action) {
  3. try {
  4. const data = yield call(Api.fetchUser, action.payload.url);
  5. yield put({type: "FETCH_SUCCEEDED", data});
  6. } catch (error) {
  7. yield put({type: "FETCH_FAILED", error});
  8. }
  9. }

然后在每次 FETCH_REQUESTED action 被发起时启动上面的任务。

  1. import { takeEvery } from 'redux-saga'
  2. function* watchFetchData() {
  3. yield* takeEvery('FETCH_REQUESTED', fetchData)
  4. }

在上面的例子中,takeEvery 允许多个 fetchData 实例同时启动。在某个特定时刻,我们可以启动一个新的 fetchData 任务,
尽管之前还有一个或多个 fetchData 尚未结束。

如果我们只想得到最新那个请求的响应(例如,始终显示最新版本的数据)。我们可以使用 takeLatest 辅助函数。

  1. import { takeLatest } from 'redux-saga'
  2. function* watchFetchData() {
  3. yield* takeLatest('FETCH_REQUESTED', fetchData)
  4. }

takeEvery 不同,在任何时刻 takeLatest 只允许执行一个 fetchData 任务。并且这个任务是最后被启动的那个。
如果之前已经有一个任务在执行,那之前的这个任务会自动被取消。