首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >takeEvery和takeLatest.为什么?什么时候使用?同时使用?

takeEvery和takeLatest.为什么?什么时候使用?同时使用?
EN

Stack Overflow用户
提问于 2020-05-24 09:57:45
回答 4查看 23K关注 0票数 27

我不清楚何时使用takeEvery以及何时使用takeLatest?在复古传奇里。

通过阅读官方文件,我得到了一个基本的区别。但是,在takeEvery中创建并发操作的用途是什么(例如,用户以快速的速度连续点击加载用户按钮2次,第二次单击将发出USER_REQUESTED,而对第一次单击的fetchUser尚未终止)

代码语言:javascript
运行
复制
import { takeEvery } from `redux-saga/effects`

function* fetchUser(action) {
  ...
}

function* watchFetchUser() {
  yield takeEvery('USER_REQUESTED', fetchUser)
}

有谁能解释一下。因为我对复古传奇一无所知。

提前谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-05-24 11:10:28

这是每个用例都需要考虑的问题。

在这些情况下,您可以使用takeEvery

  1. 对于sagas来说,这不是异步的,因此没有理由取消它们。takeLatest在这里也可以工作,但是当读取代码时,它可能会给出错误的指示,表明有什么东西需要取消。
  2. 有时,当行动在某种程度上不同的时候,每次。想象一下,你有一部电影,你在添加带有电影体裁的标签。每次触发动作,您都会得到不同的类型,即使它是相同的动作类型。用户可以比从服务器获得响应更快地添加类型。但是,仅仅因为你快速地添加了多种类型并不意味着你想要停止传奇添加前一个。
  3. 当您对多个不同项目具有相同的加载操作时的廉价实现。例如,你有电影列表,每个都有“加载细节”按钮。(让我们忽略一个事实,即一旦加载开始,您可能应该隐藏或禁用按钮)。对于一部电影,数据总是相同的,但它们之间的数据是不同的。当您单击“电影1”的“加载详细信息”时,您不希望取消对“电影2”的数据加载。由于它是电影的动态列表,所以动作类型每次都是相同的,差异可能类似于电影在动作中的id。 在理想的实现中,您可能应该为同一个电影/id取消以前的load,但是这需要更复杂的代码,所以如果您只执行一些简单的应用程序,您可能会决定忽略它,只允许多次运行相同的电影。这就是我称之为“廉价实施”的原因。
票数 20
EN

Stack Overflow用户

发布于 2020-10-28 17:36:30

虽然@Martin的可靠答案涵盖了这个问题,但我想更详细地阐述takeEvery和takeLatest上的细节和差异,以及何时可以使用它们,以便您可以得到它们的可能用例。

TLDR:

当需要返回所有以前的任务时,可以使用takeEvery。例如,从一个气象站获取某一段时间内的温湿度数据,将其存储在数据库中,并以图形的形式显示--在本例中,所有以前的sagas及其返回值都是interset和的值,而不仅仅是最新的

如果一个内部/外部实例或一个接口的用户可以触发多个连续的操作,并且只有最后一个值的结论是可取的,则可以使用takeLatest。一个很好的例子是快速调用broker来实时显示股票价值,其中只有(最新/最近的价值是)感兴趣。

详细信息:

将takeEvery和takeLatest看作是redux底层API之上的辅助函数,当特定操作被分派到商店时,它们正在包装内部操作,例如生成任务。调用它们会在发送到与模式匹配的商店的每个动作上产生一个传奇。

takeEvery:

最常见的takeEvery函数在其行为和方法上非常类似于redux。它基本上是一个模式或通道的yield takeyield fork的包装器。

关于takeEvery的线索是,它允许并发/同时启动一个定义的操作/任务的多个实例(例如下面示例中的fetchSomeThing )。

与takeLatest不同,您可以在一个或多个以前的fetchSomeThing实例尚未完成/终止时启动一个新的fetchSomeThing任务,因此仍在挂起。请记住,不能保证任务将以相同的顺序结束/完成。要处理无序响应,可以使用takeLatest。

来自官方的文档

takeEvery(pattern, saga, ...args)

在发送到与模式匹配的商店的每个动作上产生一个传奇。

  • pattern:String / Array函数
  • saga:函数-生成器函数
  • args:要传递给已启动任务的数组参数。takeEvery将将传入的操作添加到参数列表中(即该操作将是提供给saga的最后一个参数)

您还可以将通道作为参数传递,而不是传递与takeEvery(模式、佐贺、...args)相同的行为模式。

takeLatest:

相反,takeLatest助手函数只获得被触发的最新请求的响应,该响应可以看作是模式或通道yield take的包装器,以及附加的if语句检查是否存在lastTask (之前的任务仍在等待中),然后通过yield cancel和随后的yield fork终止该yield cancel和后续yield fork,从而生成当前任务/操作。

来自官方的文档

takeLatest(pattern, saga, ...args)

只会触发最新请求的响应。

  • pattern:String / Array函数
  • saga:函数-生成器函数
  • args:要传递给已启动任务的数组参数。takeLatest将将传入的操作添加到参数列表中(即该操作将是提供给saga的最后一个参数)

与takeEvery类似,您也可以将通道作为参数传递,而不是模式。

票数 32
EN

Stack Overflow用户

发布于 2021-10-28 18:58:14

用几句话来概括一下,

  • takeEvery允许处理并发操作。例如,用户连续2次快速单击Load用户按钮,第二次单击将分派USER_REQUESTED操作,而对第一个操作启动的fetchUser尚未终止。 takeEvery不处理来自任务的无序响应。不能保证任务的终止顺序与开始的顺序相同。要处理无序响应,可以考虑使用takeLatest。
  • 相反,takeLatest在每个分派的USER_REQUESTED操作上启动一个新的fetchUser任务。由于takeLatest 取消了以前启动的任何挂起的任务,因此我们确保如果用户快速触发多个连续的USER_REQUESTED操作,我们将只使用最新的操作来结束

多库:https://redux-saga.js.org/docs/api/

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61984294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档