Search code examples
redux-saga

How to create setTimeout loop for yield put()


I have a saga watcher:

function* watchSetRefreshInterval() {
    yield takeLatest(SET_LOOP, setLoop);
}

and a setLoop saga

function* setLoop() {
        yield put({type: ANOTHER_WATCHER });
}

I want yield put({type: ANOTHER_WATCHER }); to happen with interval

This does not work

setTimeout(function timeoutFn(){
        yield put({type: ANOTHER_WATCHER });
        setTimeout(timeoutFn, 5000);
}, 5000);

You cannot use yield in non-generator function, making timeoutFn a generator does not work as well.

How can I call yield put in an interval. I don't want to use

while(true) {
        yield delay(5000);
        yield put({type: ANOTHER_WATCHER });
}

I want to use setTimeout function.


Solution

  • What you want is a classic example of an Event Channel.

    Check out the link below -

    https://redux-saga.js.org/docs/advanced/Channels.html

    Sample-

    import { eventChannel, END } from 'redux-saga'
    
    function countdown(secs) {
      return eventChannel(emitter => {
          const iv = setInterval(() => {
            secs -= 1
            if (secs > 0) {
              emitter(secs)
            } else {
              // this causes the channel to close
              emitter(END)
            }
          }, 1000);
          // The subscriber must return an unsubscribe function
          return () => {
            clearInterval(iv)
          }
        }
      )
    }
    

    Hope this helps! 😇