首页 > 解决方案 > 如何递归调用 redux saga watcher

问题描述

我正在努力递归地调用 redux-saga 观察者,它与 setInterval 函数的工作方式相同,其中观察者函数应该在每 n 秒后调用一次,我们可以像 clearInterval 一样清除间隔。

我的要求——

每 n 秒后递归调用 redux-saga watcher。这里 n 存储在 store 中,并且可以更新。因此,当 n 将在 store 中更新时,我们需要停止旧的 watcher 函数(如 clearInterval)并以更新的 n 秒重新启动旧的递归 watcher。

标签: react-reduxredux-saga

解决方案


import { delay } from "redux-saga";
import {
  all,
  take,
  select,
  cancel,
  put,
  takeEvery,
  fork,
} from "redux-saga/effects";

export function* loop() {

  // Get the store
  const state = yield select();
  let n = state.n;

  // Will keep looping with a delay of n milliseconds,
  // where n is accessed from the store.
  while (true) {
    yield delay(n);
    yield put({ type: "CALLED_AGAIN" });
  }
}

export function* startProcess() {

  // Start the loop
  let task = yield fork(loop);
  let action = yield take(["END_PROCESS", "INC_TIMER"]);

  switch (action.type) {
    case "END_PROCESS":

      // For stopping the loop
      yield cancel(task);
      break;
    case "INC_TIMER":

      // While changing the duration of the timer:
      // 1) End the previous loop
      yield cancel(task);

      // 2) Change the timer(stored as n here)
      yield put({ type: "INC_TIMER_COMPLETED" });

      // 3) Start the recursive calls again
      yield put({ type: "START_PROCESS" });
      break;
    default:
      break;
  }
}

export function* watchStartTasks() {
  // Initially "START_PROCESS" is dispatched to start the recursive calls.
  yield takeEvery("START_PROCESS", startProcess);
}

export default function* rootSaga() {
  yield all([watchStartTasks()]);
}

推荐阅读