关于RXJS,何时需要取消订阅 / 可观测对象的冷热之分

13 篇文章 0 订阅

首先概念澄清:

observable有两种数据类型:Clod and Hot

实际工作的两种情况:(一个Observable对象有不同Observer对象订阅,且不是同时订阅):

第一种Hot 错过的数据就错过了,从订阅那一刻开始接受(生活中用电视机看电视节目)

第二种Clod 需要完整的数据,错过的数据也需要获取(互联网看电视节目)

顺带一提:

        Hot Observable实现的是多播;

        Cold Observable实现的是单播。

在工作中最常见的疑惑:当通过http请求返回的observable我们需要对它做后续处理,订阅一个observer(observer是一个行为处理函数,包含对返回结果的一系列处理)。但是,当你使用subject的时候,发现他会源源不断的发送值,根本停不下来。

对于结束 Observable,释放内存的方式有三种方式:

  • 第一种,Observable 完成值的发送,执行 Observable.onComplete()

  • 第二种,Observable 发生错误,执行 Observable.OnError()

  • 第三种,订阅者主动取消订阅,执行 subscription.unsubscribe()

对于Observable.onComplete()Observable.OnError(),RxJS 自身会处理这两种情况,所以不需要在代码里再手动取消订阅释放内存。对于第三种方式,Observable 还在源源不断的发送值,订阅者想主动取消订阅,那就需要在代码里调用unsubscribe()取消订阅释放内存。

在 Angular 项目中,常用到的订阅以及是否需要调用 unsubscribe() 取消订阅,有以下几种:

  • Angular 中通过 HttpClient 执行 Http Request 返回的 Observables,不需要调取消订阅。

  • Angular AsyncPipe,不需要调用 unsubscribe()取消订阅。

  • 通过 Subject,BehaviorSubject,AsyncSubject,ReplaySubject 在各个 Component 之间通信,需要调用 unsubscribe()取消订阅。

  • RxJS 自带的一些操作符:take,takeWhile,first 等等,不需要调用 unsubscribe()取消订阅。

Http Request 返回的 Observables

Aangular 源码会处理完成的 Http Response Observables

在 Http Response 结束时,如果 Request 成功会调用responseObserver.complete(),如果 Request 失败会调用responseObserver.error(response),complete()/error() 方法会结束当前 responseObserver。

Angular 中通过 HttpClient 执行 Http Request 返回的 Observables 是 Cold Observable 并且只发送一个值,Cold Observable 在值发送完成以后,RxJS 会执行 OnCompleted 方法,自动释放资源。

Angular Async Pipe

......
......
@Injectable()
@Pipe({name: 'async', pure: false})
export class AsyncPipe implements OnDestroy, PipeTransform {

  ......
  private _subscription: SubscriptionLike|Promise<any>|null = null;
  ......
  constructor(private _ref: ChangeDetectorRef) {}

  ngOnDestroy(): void {
    if (this._subscription) {
      this._dispose();
    }
  }
  ......
  ......

在 ngOnDestroy 方法中,会执行this._dispose()把 AsyncPipe 的订阅销毁。

通过四种 Subject 在各个 Component 之间通信

在 component 之间通信,我们会用到 Subject,BehaviorSubject,AsyncSubject,ReplaySubject 这四种 subject,它们都是Hot Observable,Hot Observable 不管有没有被订阅都会源源不断的发送值。如果订阅者要主动取消订阅,就必须手动调用unsubscribe() 取消订阅。在 Angular component 有个钩子函数:ngOnDestroy,在 commponet 被销毁之前执行,所以一般都是把 Subscription 的 unsubscribe 放在这个函数里执行,代码如下:

    ngOnDestroy() {
        this.subscription.unsubscribe();
    }

RxJS 自带的一些操作符:take,takeWhile,first

在用这些操作符,比如 take(1),拿到 Observable 发送的第一个值之后,RxJs 会主动的停止当前的 Observable,也就是销毁当前 Observable,并不需要手动再调用 unsubscribe()取消订阅。

origin thinking:RXJS解决NGZORRO下拉框组件漂移的问题_董厂长的博客-CSDN博客Subscription是一个对象,表示一种可被处置的资源,通常指代一个Observable流的执行过程。Subscription有一个重要的方法unsubscribe(),不需要参数,仅仅用来释放掉subscription实例所...问题描述:使用Angular+NGZORO时候,组件库的下拉框或时间选择框会出现滚动页面,然后漂移的问题。实际的想法是,滚动页面的时候,要么下拉框消失,要么随着页面滚动。那么想法就是,当用户滚动的时候会发出一个流stream,以此创建一个可观察对象observable。...https://blog.csdn.net/dongnihao/article/details/126271230?spm=1001.2014.3001.5502

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董厂长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值