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

问题描述 投票:0回答:2

我想从一个传奇中调用另一个传奇。

saga 当然是一个生成器函数,并且是异步的。

我应该使用

yield *
还是应该始终使用
yield

function* mySaga({ payload: { id, name } }) {
    yield myOtherAsyncSaga(); // when to use yield *?
}
javascript redux redux-saga
2个回答
9
投票

saga 当然是一个生成器函数,并且是异步的。
我应该使用yield * 还是应该始终使用yield?

要完全回答这个问题,首先需要了解传奇、中间件、流程管理器和生成器函数通常如何工作。事实上

redux-saga
实现了两个方面:redux store 的中间件,它拦截和注入自定义操作,以及 async process manager,它有自己的刻度回调域并帮助执行异步操作。

接下来,每个客户端实现的传奇函数只是效果创建者。事实上,客户端 saga 函数是这样实现的,它实际上不执行任何操作,而是创建效果 -

call
take
put
等。此外,saga 本质上不是同步或异步 - 它只是委托saga 流程管理器的一些行为,并执行请求的操作 - 例如,等待承诺。
当然,您可以在客户端 saga 中手动执行 Promise/async 处理,但此类操作将从 saga 事件周期中掉出。

因此,

redux-saga
内部希望客户端传奇只是一个迭代器,它返回适当的效果,并且可能在闭包激活上下文中存储一些信息 - 在
while(true)
类似传奇流程的情况下。因此,
redux-saga
中没有用例,其中
yield *
是强制性的,因为
yield *
只是将后续迭代器重新委托给上层。


1
投票

TLDR:始终使用

yield*
来提高 TS 中的性能和正确的类型解析

如果你是JS地,

yield
给中间件一个Generator,中间件会自动迭代它。如果您使用
yield*
,您将迭代生成器并将所有项目生成给中间件。 这种情况下没有什么大的区别,只是命中中间件速度较慢。

使用 TypeScript 时,情况会发生一些变化:

yield
意味着生成器的迭代将在中间件中发生,因此我们的类型将不正确。如果我们使用
yield*
,迭代将在我们的范围内发生,并且 TS 将能够检测到正确的类型。

有一个小型 TS 库可以更好地说明这一点:https://www.npmjs.com/package/typed-redux-saga

© www.soinside.com 2019 - 2024. All rights reserved.