简体   繁体   English

我什么时候应该在 redux-saga 中使用 yield* 与 yield?

[英]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 ?我应该使用yield yield *还是应该始终使用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. 完全回答一个问题,首先有必要理解为saga,中间件,流程管理器和生成器功能通常是有效的。 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. 事实上, redux-saga实现了两个方面:用于redux存储的中间件,用于拦截和注入自定义操作,以及异步进程管理器 ,它具有自己的tick回调域并帮助执行异步操作。

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. 事实上,客户端传奇函数是以这样的方式实现的,它实际上没有做任何事情,但是效果创建 - calltakeput等等。此外,saga本质上不是同步或异步 - 它只是将一些行为委托给saga进程管理器,并执行请求的操作 - 例如,等待承诺。
Of course, you can manually perform promise/async handling in client saga, but such actions will fall from saga event cycle. 当然,您可以在客户端传奇中手动执行promise / async处理,但此类操作将从saga事件周期中删除。

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. 所以, redux-saga内部需要从客户端传奇只是一个迭代器 ,它返回适当的效果,并可能在闭包激活上下文中存储一些信息 - 如果是while(true) - 就像saga进程一样。 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. 因此,在redux-saga没有用例,其中yield *是必需的,正弦yield *只是将后续迭代器重新委托给上层。

TLDR:域名注册地址:

  • in JS, it doesn't matter在JS中,没关系
  • in TS, always use yield* for correct type resolution在 TS 中,始终使用yield*进行正确的类型解析

If you are on JS land, yield gives the middleware a Generator and the middleware will automatically iterate it.如果你在 JS 领域, yield给中间件一个 Generator,中间件会自动迭代它。 If you use yield* , you are iterating the generator and yielding all the items to the middleware.如果您使用yield* ,则您正在迭代生成器并将所有项目生成给中间件。 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.使用 TypeScript 时,情况会发生一些变化: yield意味着生成器的迭代将发生在中间件中,因此我们的类型将不正确。 If instead we use yield* , the iteration will happen on our scope and TS will be able to detect the proper types.如果我们改为使用yield* ,迭代将发生在我们的作用域上,TS 将能够检测到正确的类型。

There is a small TS library that illustrates this better: https://www.npmjs.com/package/typed-redux-saga有一个小的 TS 库可以更好地说明这一点: https : //www.npmjs.com/package/typed-redux-saga

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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