简体   繁体   中英

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 *?
}

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

Completely to answer a question, at first it is necessary to understand as saga, 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, sine yield * is just re-delegation of subsequent iterator to upper level.

TLDR:

  • in JS, it doesn't matter
  • in TS, always use yield* for correct type resolution

If you are on JS land, yield gives the middleware a Generator and the middleware will automatically iterate it. If you use yield* , you are iterating the generator and yielding all the items to the middleware. There is no difference in this case.

When using TypeScript, things change a bit: yield means that the iteration of the generator will happen in the middleware and because of that our types will be incorrect. If instead we use yield* , the iteration will happen on our scope and TS will be able to detect the proper types.

There is a small TS library that illustrates this better: https://www.npmjs.com/package/typed-redux-saga

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM