javascriptreduxredux-saga

When should I use yield* vs yield in redux-saga?


I want to call another saga from a saga.

The saga is of course a generator function, and is asynchronous.

Should I ever user yield * or should I always use yield?

function* mySaga({ payload: { id, name } }) {
    yield myOtherAsyncSaga(); // when to use yield *?
}

Solution

  • The saga is of course a generator function, and is asynchronous.
    Should I ever user yield * or should I always use yield?

    To completely answer this question, it's first necessary to understand how sagas, middlewares, process manager and generator functions generally work. In fact redux-saga implements two sides: middleware for redux store, which intercepts and injects custom actions, and async process manager, which has own tick callback domain and helps with perform async action.

    Next, every client-implemented saga function is just effect creator. In fact client saga function is implemented such way, that it actually does not do anything, but effect creation - call, take, put, etc. Also, saga is not sync or async by nature - it just delegates some behavior to saga process manager, and it perform requested actions - for example, waiting promise.
    Of course, you can manually perform promise/async handling in client saga, but such actions will fall from saga event cycle.

    So, redux-saga internals wants from client saga just to be an iterator, which returns appropriate effects and maybe store some information in closure activation context - in case of while(true)- like saga processes. So, there is no use case in redux-saga, where yield * is mandatory, since yield * is just re-delegation of subsequent iterator to upper level.