【问题标题】:unsubscribe to an Observable created by of取消订阅由 of 创建的 Observable
【发布时间】:2019-09-07 23:25:27
【问题描述】:

当我创建一个 observable 并完成它时,我直接取消订阅它

const data$ = this.httpClient.get('https://jsonplaceholder.typicode.com/todos/1').subscribe(res => {
  console.log('live', res);
  data$.unsubscribe(); // <---- works fine
});

但是说如果我使用of 创建一个 Observable 并尝试做同样的事情

const obs$ = of(1).subscribe(e => {
  console.log('test', e)
  obs$.unsubscribe(); // <--- Problem while creating Observable by of
});

这两个 observables 有什么不同?

【问题讨论】:

  • of 同步完成,因此您尝试在分配给obs$ 之前调用obs$.unsubscribe。 HTTP observable 将异步完成 - 在分配 obs$ 之后。
  • 我认为这很有道理。您可以将其发布为答案,以便我可以标记它
  • subscribe 函数应该是 pure 并且不能引用函数范围之外的变量。您的两个示例都是具有副作用的 impure 函数。虽然您的问题是针对可观察的,但如果您在源代码的其他地方执行此操作,您将继续遇到错误。这是关于该主题的教程:ultimatecourses.com/blog/pure-versus-impure-functions

标签: node.js angular typescript ecmascript-6 rxjs


【解决方案1】:

您的代码应该是导入订阅并在 ngOnDestroy 中取消订阅

import { Observable, Subscription, of } from "rxjs";
private subscription$: Subscription;

this.subscription$ = of(1).subscribe(e => {
  console.log('test', e)
});

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

更新:我的理解是 http 请求是一个可观察的,将来可能具有传入值,of 只需创建一个可观察的列表

来自@cartant 的评论

of 同步完成,因此您正在尝试调用 obs$.在分配给 obs$ 之前取消订阅。

【讨论】:

  • 这是一种做法。我的问题更多是为什么。
  • 我认为在这种情况下您不能立即取消订阅。这是许多开发人员推荐的手动订阅和取消订阅可观察的方式
【解决方案2】:

如果您的组件中只有一个 observable,那么通过以下方式取消订阅是最简单的方案:

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

更复杂的场景是有多个可观察对象,此时您不会在订阅subscriptions: Subscription[] 时推送每个可观察对象,而在销毁数组时取消订阅数组ngOnDestroy(){ this.subscriptions.forEach(sub => sub.unsubscribe()); } 中所有添加的订阅

或者你可以使用npm package

【讨论】:

  • 为什么我必须使用 package ?您可以使用 takeWhile 取消订阅
  • @TonyNgo 你的意思是定义一个标志来表示你什么时候应该取消订阅?
【解决方案3】:

为了确保在组件中取消订阅,我建议创建一个Subject,它在ngOnDestroy() 中发出,如下所示:

destroy$ = new Subject<boolean>();
...
ngOnDestroy() {
  this.destroy$.next(true);
}

并在组件中的每个Observable 上添加takeUntil

myObs$.pipe(
  takeUntil(this.destroy$),
  tap(stuff => doStuff())
).subscribe();

这样可以避免大量不必要的Subscription 变量污染事物。

【讨论】:

    猜你喜欢
    • 2019-12-20
    • 2019-03-19
    • 1970-01-01
    • 2020-08-29
    • 1970-01-01
    • 2017-04-10
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多