我想从一个传奇中调用另一个传奇。
saga 当然是一个生成器函数,并且是异步的。
我应该使用
yield *
还是应该始终使用 yield
?
function* mySaga({ payload: { id, name } }) {
yield myOtherAsyncSaga(); // when to use yield *?
}
saga 当然是一个生成器函数,并且是异步的。
我应该使用yield * 还是应该始终使用yield?
要完全回答这个问题,首先需要了解传奇、中间件、流程管理器和生成器函数通常如何工作。事实上
redux-saga
实现了两个方面:redux store 的中间件,它拦截和注入自定义操作,以及 async process manager,它有自己的刻度回调域并帮助执行异步操作。
接下来,每个客户端实现的传奇函数只是效果创建者。事实上,客户端 saga 函数是这样实现的,它实际上不执行任何操作,而是创建效果 -
call
、take
、put
等。此外,saga 本质上不是同步或异步 - 它只是委托saga 流程管理器的一些行为,并执行请求的操作 - 例如,等待承诺。因此,
redux-saga
内部希望客户端传奇只是一个迭代器,它返回适当的效果,并且可能在闭包激活上下文中存储一些信息 - 在while(true)
类似传奇流程的情况下。因此,redux-saga
中没有用例,其中yield *
是强制性的,因为yield *
只是将后续迭代器重新委托给上层。
TLDR:始终使用
yield*
来提高 TS 中的性能和正确的类型解析
如果你是JS地,
yield
给中间件一个Generator,中间件会自动迭代它。如果您使用 yield*
,您将迭代生成器并将所有项目生成给中间件。
这种情况下没有什么大的区别,只是命中中间件速度较慢。
使用 TypeScript 时,情况会发生一些变化:
yield
意味着生成器的迭代将在中间件中发生,因此我们的类型将不正确。如果我们使用 yield*
,迭代将在我们的范围内发生,并且 TS 将能够检测到正确的类型。
有一个小型 TS 库可以更好地说明这一点:https://www.npmjs.com/package/typed-redux-saga