Shubham
Shubham

Reputation: 1201

How to call redux saga watcher recursively

I'm struggling to calling the redux-saga watcher recursively which would work same as setInterval function, In which the watcher function should be call after every n seconds and we could clear the interval like clearInterval.

My Requirement -

Calling redux-saga watcher recursively after every n seconds. Here n is stored in the store and it can be updated. So when n will updated in the store, we need to stop the old watcher function (like clearInterval) and re-initiate the old recursively watcher with updated n seconds.

Upvotes: 1

Views: 1929

Answers (2)

10101010
10101010

Reputation: 1821

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()]);
}

Upvotes: 1

Martin Kadlec
Martin Kadlec

Reputation: 4985

The answer will change depending on some criteria - like whether you want to wait N ms after N is changed or if on clear you want to cancel the worker - but this could give you rough idea:

function * rootSaga() {
    let prevTask
    yield takeEvery(CHANGE_N, function*() {
        if (prevTask) prevTask.cancel();
        const n = yield select(getN);
        task = yield throttle(n, FOO, fooSaga);
    });
}

If throttle is not enough you might want to replace it with custom watcher using delay and fork.

Upvotes: 0

Related Questions