跳到内容
达斯

照顾RxJS开发人员的常见错误

1+

RxJS的常见错误

作为开发人员,我处于RxJS观点的中级水平。我的经验是使用Angular的RxJava和RxJS。在此博客中,我已经发布了一个 RxJs核心上的速成课程.

照顾RxJS开发人员的常见错误
RxJS开发人员的常见错误

今天,当我们使用RxJS时,我将分享一些常见的错误。作为开发人员,本文将对您有所帮助。让’开始本教程。

取消订阅的使用

我和许多其他人就该主题进行了详尽的讨论,但这仍然是我通常看到的最常见的错误—即不取消订阅流 完全没有.

这会产生各种后果,例如:

  • 导致内存泄漏
  • 导致不必要的回调
  • 可能会导致您的应用程序出现严重错误

取消订阅Observable的最好,最优雅的方法是使用在组件销毁时发出值的主题。

另外,您可以通过订阅在组件上维护类属性,并在组件被销毁时取消订阅。

It’s pretty important, 不要’t forget.

忽略初始值

这在Angular表单中很常见。假设您订阅了一条流,期望获得价值—但你永远得不到一个。那怎么可能?

好— sometimes it’是由于未使用初始值初始化流,并且从未调度事件。

这里’是Angular的常见情况’s forms:

角形
的JavaScript
1
2
3
4
5
6
const 名称 = 表格控件(吉安卡洛(Giancarlo));
const 表格组 = 表格组({ 名称 });
const 价值变化$ = 表格组.价值变化;
价值变化.订阅(() => {
    // 做一点事
});

除非用户更改 名称以某种方式使用FormControl,将永远不会调用该回调。但—我们确实希望订阅使用的初始值发出 表格组 (很多人希望它会这样做)。

在这种情况下,我们需要使用运算符来推送初始值 从...开始:

运算符startWith
1
2
3
4
5
6
const 价值变化$ = 表格组.价值变化.(
  从...开始(表格组.)
);
价值变化.订阅(() => {
    // 做一点事
});


在这种情况下,我们将使用表单的初始值接收到一个发射,并且此后发射所有更改。

选择错误的运算符

那里有很多运营商—虽然你当然不’不需要全部学习它们,您需要确保您了解所使用的每个细节。

细微的差异可能会产生重大后果。

示例:mergeMap与switchMap

最常用的运算符之一是 mergeMap。该运算符使您可以展平内部的Observable并为每个事件维护许多活动流:在某些情况下这很好,而在其他情况下不是很理想。

在许多情况下,您可能只想维护1个活动订阅。例如,如果您有一个事件,该事件的事件调用HTTP端点,则可能要取消传出的请求,而只调用最新的请求:在这种情况下,您可以’会更好 switchMap.

如果你’re not careful, mergeMap 可能会导致重复和不必要的订阅,而 switchMap can lead to 比赛条件。最终,两者都可能导致错误和代码故障。

选择错误的运算符
选择错误的运算符

This is one example of the many, sometimes tiny, differences that make RxJS 经营者.

正如我上面所说—您不需要了解每个Rx运算符。但是,您确实需要了解您所拥有的产品的细微特点。’重新使用并与其他同类产品进行比较,以了解哪种类型适合您的情况。

您应该注意的其他显着差异:

  • 邮编vs叉子加入vs组合最新vs种族
  • 合并与合并
  • 计时器与间隔
  • 永不虚无
  • 来自
  • 缓冲区与窗口

Note: 如果你 want any other comparison with detail then comment us below.

使用错误的主题类型

不要犯的另一个重要错误是不要为任务选择错误的主题类型。

主题是Observable的一种特殊类型,它使您可以在流中推送值,也可以通过订阅它来检索它们。虽然正常 Subject 可能涵盖大多数情况,您应该注意一些细微的差异。

后期订阅者

一种常见的情况是您的主题在观察者订阅其更改之前发出事件。如果你’期望您的订户收到数据,您’再走运:它赢了’t.

在这种情况下,您应该选择 ReplaySubject,它可以将收到的所有事件重播给后期订阅者。当您只想将最新值保留在内存中时(通过定义其缓冲区大小可以执行此操作),它也特别有用。

另一种选择是 BehaviorSubject —而是需要一个值才能定义。

订阅回调中的命令式逻辑

RxJ的最大优点之一是,组合运算符并重用其逻辑是一种构建可重用代码位的非常好(且简便)的方法。

一旦订阅了Observable,编写Rx代码的许多好处就结束了:我们在订阅回调中编写的逻辑不是Rx-land,而是’是我们代码中FRP结尾的开始。

我并不是说您永远都不要订阅,但我的建议是使订阅回调中的逻辑尽可能小—并尽可能避免直接订阅(例如,使用Angular async pipe).

在订阅中使用逻辑的缺点是什么?

有限的可重用性

RxJS流是可管道的,这意味着它们可以组合和扩展,因此可以重用。

每当您订阅并在订阅中执行逻辑时,您就会带走一些本可以卸载给Rx运算符的逻辑:

的JavaScript
1
2
3
4
5
6
7
8
9
10
11
const 所有项目$ = 这个.服务.项目$.(
  过滤(布尔型)
);
const 不要eItems$ = 所有项目$.(
   地图(项目 => 项目.过滤(项目 => 项目.不要e)),
);
const numberOfRemainingItems$ = 结合最新(
  [所有项目$, 不要eItems$]
).(
   地图(([项目, 不要eItems]) => 项目 - 不要eItems),
);

如您所见,创建中间流或将逻辑卸载到单独的运算符上,是在整个应用程序中重用逻辑的绝佳方法。

根据经验:

  • 无需检查订阅中的值是否真实,您可以轻松地与运营商联系 过滤器(布尔)
  • 不要’转换订阅中的数据
  • 副作用:例如,显示/隐藏加载图标可以通过 tap or/and the finalize operators

较少声明

让’请参见命令式和声明式代码段之间的示例:

的JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
用户sDashboardComponent {
  使用者: 用户[];
  活性Users: [];
  被禁止Users: [];
  建设者(私人的 服务: 用户sService) {
     这个.服务.使用者$.订阅(使用者 => {
        如果 (使用者) {
          这个.使用者 = 使用者;
          这个.活性Users = 使用者.过滤(用户 => 用户.活性);
          这个.被禁止Users = 使用者.过滤(用户 => 用户.被禁止);
        }
     });
  }
}


现在,让’s转换以上声明性流:

的JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
用户sDashboardComponent {
  使用者$ = 这个.服务.使用者$.(
    过滤(布尔型)
  );
  活性Users$ = 这个.使用者$.(
    地图(使用者 => 使用者.过滤(用户 => 用户.活性)),
  );
  被禁止Users$ = 这个.使用者$.(
    地图(使用者 => 使用者.过滤(用户 => 用户.被禁止)),
  );
  建设者(私人的 服务: 用户sService) {}
}

话虽如此,唐’别忘了订阅,否则,您的可观察物将永远不会发出。

最后的话

Rx是一个非常出色的库和工具,可以帮助您轻松处理应用程序的复杂异步方面。它’也很大,并且经常被误解。

确保遵循上述建议,至少可以确保您’重新处理错误或您花费数小时试图修复的错误的极为常见的原因。

综上所述

  • 总是退订
  • 唐’如果期望一个初始值,则省略
  • Learn well the 经营者 that you’re using. Small differences 可导致 big mistakes.
  • 您应该使用正确的主题类型。
  • 在流中尽可能声明性地编写逻辑。同样,将逻辑与自定义运算符或中间流一起重用。

如果您需要任何澄清,或者您认为不清楚或错误的地方,请发表评论!

1+
概要
照顾RxJS开发人员的常见错误
文章名
照顾RxJS开发人员的常见错误
描述
RxJS的常见错误,今天我将分享一些使用RxJS的常见错误。作为开发人员,本文将对您有所帮助。
作者
达斯
发布者名称
达斯
出版商徽标
达斯