取消订阅 Rxjs finalize 操作符

Posted

技术标签:

【中文标题】取消订阅 Rxjs finalize 操作符【英文标题】:unsubscribe to the Rxjs finalize operator 【发布时间】:2020-10-07 12:20:38 【问题描述】:

问:我有一个问题。 finalize 操作符在源完成或完成 Observable 时被调用。这很清楚。但是我们如何预测它不会因为 Source observable 的变化而再次发出值呢?或者finalize 将在完成第一次发射后终止原始 Observable。即不再像take(1) 这样的源发出。

我使用AngularFireStorage module 下载网址。我需要在它返回 URL 后完成 observable。我怎样才能做到这一点?即无需在此处取消订阅。

这会奏效还是更好的方法?获取下载地址后如何自动退订?

     afUploadTask.snapshotChanges().pipe(take(1), finalize(() => this.downloadURL 
= afStorageReference.getDownloadURL())).subscribe();

这是文档中的原始示例:

task.snapshotChanges().pipe(
        finalize(() => this.downloadURL = fileRef.getDownloadURL() )
     )
    .subscribe()

【问题讨论】:

【参考方案1】:

您的目标是等待上传任务完成,然后设置 url。您可以完全按照示例中的方式进行操作,或者像这样:

afUploadTask.snapshotChanges().subscribe(
  null,
  null,
  () => this.downloadURL = afStorageReference.getDownloadURL()
);

这也是等价的:

afUploadTask.snapshotChanges().pipe(last()).subscribe(
  () => this.downloadURL = afStorageReference.getDownloadURL()
);

添加take 运算符将导致在url 可用之前提前完成。您无需担心取消订阅,因为上传完成后可观察对象将完成。已完成的 observable 不会阻止垃圾回收或导致内存泄漏。

【讨论】:

我希望无论如何我都需要使用finalize,因为官方文档是这样规定的。请看这里:github.com/angular/angularfire/blob/master/docs/storage/… 这里的关键是我需要一个可下载的 URL。没有它毫无意义。 好的...我认为你搞错了,你为什么要添加take(1) 是的,这就是这里的问题。我想在这里有一个更好的方法来自动退订。否则内存泄漏等。 内存泄漏与完成 observables 无关。完成相当于取消订阅。如果 finalize 运行或完成处理程序运行,则 observable 已完成并有资格进行垃圾回收

以上是关于取消订阅 Rxjs finalize 操作符的主要内容,如果未能解决你的问题,请参考以下文章

#RXJS# 基础

取消订阅 RxJS Observables

任何需要先取消订阅 RxJS()

取消 rxjs 中的 http 订阅

RxJS 迁移 5 到 6 - 使用 TakeUntil 取消订阅

取消订阅 Rxjs Observables