Angular 2 可观察间隔锁定 UI

2024-05-11

当我使用Observable.Interval要执行 UI 的 http 刷新,如果间隔太快,它会锁定 UI 上的按钮,使其无法工作。按钮没有记录点击,似乎是一个计时问题。如果我增加时间并因此错过了 get 调用,则按钮可以工作,但数据会延迟更新。

Interval

this.dataSub = Observable.interval(1000).subscribe(x => {
  this.getData();
})

getData

 getData(): void {
     this.dataService.getData()
         .subscribe(
              data => this.data = data,
              error => console.log("Error HTTP Get Service" + this.data),
              () => {});
 }

是否有最佳实践,或者我应该做些什么来刷新 UI 但不锁定按钮


理论

一般来说,您应该尽可能避免显式订阅可观察量。相反,使用所有可用于将所有源/输入可观察量组合成在视图中使用的一个或多个可观察量的运算符(是的,找出正确的运算符可能非常棘手)async pipe.

不要忘记 JS 是单线程的(除了工人)。你的 UI 和大多数 Angular 代码必须共享一个线程,因此长时间运行的 JS 会锁定你的 UI。

这有三个主要好处:

  1. 几乎不可能造成内存泄漏。如果您不记得总是在ngOnDestroy()hook 或当您不再关心它时,每当您手动订阅时,您都会面临内存泄漏的风险。鉴于async当使用它的组件/元素被破坏时,管道将正确取消订阅 - 您无需担心它。
  2. 做更少的工作。使用像这样的运算符switchMap(), switchLatest()等等,您可以取消和清理被取代的 HTTP 调用和其他昂贵的操作,或者如果不再需要它们,甚至可以在它们开始之前停止它们。不要做超出你必须做的事情。这通常也意味着变更检测不必运行太多,这意味着更好的性能。
  3. 更干净的代码。更少的成员变量,更多的函数式代码。是的,当你学习 Rx 时,理解可能会有点困难,但它会变得更容易。

在实践中

考虑到所有这些,您如何将其应用到您的代码中?

您可能没有意识到的一件事(很多人都没有)是,如果您的DataService.getData()方法是这样的:

getData(): Observable<MyData[]> {
    return this.http.get('http://some.url/data').map(res => res.json());
}

然后每次你订阅由Http服务,提出新请求。这就是你想要的,但你don'tWant 是在发出新请求后立即处理任何先前请求的结果。

因此,您可以在控制器中使用类似以下内容来将来自最近请求的最新数据组成一个可观察值:

 ngOnInit() {
     // (I follow a convention where observable properties end in $)
     this.data$ = Observable.interval(1000).flatMapLatest(() => {
         return this.dataService.getData();
     });
 }

没有订阅,只是创建的可观察对象。然后在您看来,只需将异步管道与data$财产,你就是金子。

例如:

<ul *ngFor="let d of (data$ | async); trackBy: d?.id">
    <li>{{d.name}}</li>
</ul>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular 2 可观察间隔锁定 UI 的相关文章

随机推荐

  • 更新或插入 MySQL Python

    如果记录已存在 我需要更新一行 如果不存在 我需要创建一个新记录 我理解 ON DUPLICATE KEY 将使用 MYSQLdb 完成此操作 但是我无法使其正常工作 我的代码如下 cursor database cursor cursor
  • 在VB.NET中获取文件修改日期

    我的文件夹中有许多文件 我需要获取最后修改日期 所以我用了 FDate IO File GetLastWriteTime FName 对于某些文件 它工作正常 但对于其他文件 我得到的日期为 1 1 1601 但是当我在 Windows 资
  • Tkinter:通过多处理启动进程会创建不需要的新窗口

    我计划围绕数值模拟编写一个小型 GUI 这就是我现在使用 Tkinter 的原因 模拟应在单独的进程中从 GUI 启动 为了玩一下 我定义了一个函数 random process 来生成成对的 randn 数字 这应该是一个真正的模拟过程
  • 在Python中将用户昵称转换为正式名字

    我正在尝试根据 Python 中的用户名字和姓氏映射来自不同系统的用户 一个问题是 名字在很多情况下都是 昵称 例如 对于用户来说 他的名字在一个系统中是 Dave 而在另一个系统中是 David python 中有没有简单的方法可以将这些
  • 将两个sql查询合并为一个查询

    如何组合以下 2 个查询以便获得两列 PAYMODE 和付款类型 两个查询都很相似 并且针对同一个表 将两个 sql 查询合并为一个查询 这样我就不需要执行两个单独的查询 SELECT ETBL DESC TXT as PAYMODE FR
  • “array.map”是否保留原始顺序?

    我有一个User类has many Jobs 我使用以下代码映射作业 def ranges user jobs map u u start at u end at end 我有一个比较两个数组的规范 my array start1 end1
  • Winform DatagridView 数字列排序

    我只使用一个简单的 DataGridView 来保存一堆数据 有趣的是 我在特定列中有小数 但是当按小数列排序时 它的排序是错误的 例如 起始顺序可能是 0 56 3 45 500 89 20078 90 1 56 100 29 2 39
  • 创建 df 以生成给定格式的 json

    我正在尝试生成一个 df 来生成下面的 json Json数据 name flare children name K1 children name Exact size 4 name synonyms size 14 name K2 chi
  • 对 ExecuteNonQuery() 的单次调用是原子的

    对 ExecuteNonQuery 的单次调用是否是原子的 或者如果单个 DbCommand 中有多个 sql 语句 那么使用事务是否有意义 请参阅我的示例以进行说明 using var ts new TransactionScope us
  • @UniqueConstraint 和 @Column(unique=true) 选项之间的 Doctrine ORM 级别差异

    在数据库级别 使用一个选项与另一个选项来定义时没有区别独特性如下所示 虽然 UniqueConstraint在其文档中读取 它仅在 SchemaTool 模式生成上下文中有意义 两者之间是否存在 ORM 级别差异 我的意思是 当我们运行查询
  • 使用材质 UI 更改反应选择中的禁用属性

    我正在尝试使用材料用户界面更改反应应用程序中选择按钮单击的禁用属性 我的按钮代码是
  • perf stat中的cycles注释是什么意思

    8 014196 task clock 0 004 CPUs utilized 204 context switches 0 025 M sec 32 cpu migrations 0 004 M sec 0 page faults 0 0
  • 不理解..密度的行为

    在下面的数据框中 我预计密度的 y 轴值为 0 6 和 0 4 但它们是 1 0 我觉得我使用的方式显然缺少一些非常基本的东西 密度 但是我的大脑冻结了 我将如何使用 密度 获得所需的行为 任何帮助将不胜感激 df lt data fram
  • 如何在 RoR 中实施成就系统

    我正在尝试在我的 Ruby on Rails 应用程序中实现一个成就系统 但效果很差 我有一长串想要检查的成就 所有这些都是由各种控制器中的某些创建操作触发的 我的想法是我将拥有一个成就模型 其中包括控制器及其响应的操作 然后对创建进行之前
  • 如何使用c#从数据桶中获取所有文档?

    如何获取数据桶中的所有文档 我尝试过一个示例 但我只能获得一个特定的文档 这是我的代码 CouchbaseClient oclient oclient new CouchbaseClient vwspace data bucket name
  • Android Studio 3.0 - 设置未保存

    我已将 文件 gt 设置 gt 编辑器 gt 代码样式 中的 右边距 列 从默认的 100 增加到 140 不幸的是 每次重新启动 Android Studio 后 该边距都会重置 我还尝试导出和导入我的设置 但这并不能阻止重置右边距 希望
  • 为什么发送 fetch() 时我的响应数据未定义?

    我正在尝试在客户端使用 fetch 将数据发布到我的 NodeJS 服务器或从我的 NodeJS 服务器发布数据 服务器很好地收到了 post 请求 我能够记录 req 变量 但是当我 res send any data 时 客户端无法检测
  • 如何通过 libwebsocket 发送异步数据?

    我正在将 Warmcat 的 libwebsocket C 库用于小型 Websocket 服务器 我已经启动并运行了这些示例 并且可以发送数据以响应从 websocket 接收数据 例如回显发送的反向字节 但是 我无法弄清楚如何在不使用
  • 使用 flutter 处理 Appcheck 时出错

    我想在 firebase 存储中上传文件 但经过多次研究后出现了 appcheck 错误 我发现我必须在 firebase 上激活 Appcheck 而且还要在我的应用程序上激活它 在 youtube 上的谷歌视频中 我看到我必须在构建我的
  • Angular 2 可观察间隔锁定 UI

    当我使用Observable Interval要执行 UI 的 http 刷新 如果间隔太快 它会锁定 UI 上的按钮 使其无法工作 按钮没有记录点击 似乎是一个计时问题 如果我增加时间并因此错过了 get 调用 则按钮可以工作 但数据会延