最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin0浏览0评论

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

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 *?
}
Share Improve this question asked Nov 28, 2017 at 14:16 Ben AstonBen Aston 55.7k69 gold badges220 silver badges349 bronze badges 5
  • 3 Well as written, your mySaga() generator will return just one result from the other generator, and then it'll be done. The point of yield * is to effectively delegate to the other generator, and continue to return all its results until it's done. The delegating generator can yield its own values before and after that. – Pointy Commented Nov 28, 2017 at 14:21
  • So yield is behaviourally the same as yield * if the generator only returns a single result? – Ben Aston Commented Nov 28, 2017 at 14:23
  • 1 That's my understanding, yes; it would be pretty easy to verify that experimentally with a couple of trivial test functions. – Pointy Commented Nov 28, 2017 at 14:25
  • 1 It depends a lot on how the generator is consumed. If the consumer can recursively handle yielded generator objects, it might not make a difference at all. – Bergi Commented Nov 28, 2017 at 14:25
  • 1 Generally, yield would be identical to yield*in Redux, since yield will yield out the iterator, and Redux magic will make it work, just like if you have yielded out a promise. yield* just means you handle the iterator yourself, right there, while yield lets Redux handle it for you. – geon Commented Feb 21, 2020 at 8:17
Add a comment  | 

2 Answers 2

Reset to default 10

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.

TLDR: always use yield* for performance and correct type resolution in TS

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 big difference in this case, except that hitting the middleware is slower.

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

发布评论

评论列表(0)

  1. 暂无评论