【问题标题】:How to see what Observables are not completed while debugging调试时如何查看哪些 Observables 没有完成
【发布时间】:2021-12-18 04:21:14
【问题描述】:

在 Angular 应用程序中,您最终可能会拥有相当多的 Observable,并且您可能会在不再需要时忘记完成它们。因此,它们可能会意外触发,从而导致难以调试的意外副作用。

有没有办法在调试期间随时查看所有未完成的 Observable?我正在考虑一个 DevTools 工具。

【问题讨论】:

  • 你目前如何完成这些 observables?
  • 我用 take(1) 或 takeUntil(destroy$) 完成它们,有些我没有完成,它们永远保持订阅状态
  • 您可以取消订阅 Observable(例如在 ngOnDestroy 中)。为此,您可以为每个订阅创建一个变量或创建一个 const subs = new Subscription(),您可以在其中添加 (subs.add(obs$.subscribe(...))) 所有订阅并仅取消订阅 (subs.unsubscribe()) 一次 (ngOnDestroy)。

标签: angular rxjs observable rxjs-observables


【解决方案1】:

我认为没有任何明显而简单的方法可以完全满足您的需求。

但是,由于RxJS 7.3 tap() 运算符除了可以处理三种通知类型之外还可以处理三个新事件“subscribe”、“unsubscribe”和“finalize”(与使用finalize() 运算符基本相同)。 (在 RxJS 版本 defer() 和 finalize() 可以实现相同的功能。

在您的情况下,您可以收听所有“订阅”和“取消订阅”,如果它们被调用的次数相同,那么您就知道所有订阅都被手动取消订阅或源已完成/错误:

import { of, tap, delay } from 'rxjs';

let counter = 0;

const source$ = of('World')
  .pipe(
    delay(1000),
    tap({
      subscribe: () => console.log('Subscribers: ', ++counter),
      finalize: () => console.log('Subscribers: ', --counter),
    }),
  );
  
source$.subscribe();
source$.subscribe();
setTimeout(() => source$.subscribe(), 500);
setTimeout(() => source$.subscribe(), 2000);

现场演示:https://stackblitz.com/edit/rxjs-oht1ex?devtoolsheight=60

如果所有订阅者都退订了,那么您必须在最后在控制台中看到"Subscribers: 0"

请注意,tap() 必须是最后一个运算符,因此在发出延迟值后会调用 finalize 处理程序。

【讨论】:

  • 在组件订阅(但不要取消订阅)长期服务可观察对象的情况下更容易发生内存泄漏,而这些通常不会finalize
  • ... 这正是我在回答中描述的同时处理订阅和完成事件的原因
  • 哦,所以如果一个服务有一个 BehaviorSubject,你不会在服务中放置计数器,而是在每个使用和订阅服务的组件中放置一个计数器?跨度>
  • 你可以把它放到组件或服务中,这取决于你想做什么
【解决方案2】:

是的,有一个内存分析器开发工具。内存 -> 拍摄快照。做一些导致内存泄漏的事情,拍摄另一个快照并比较它们

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-10
    • 2011-09-07
    • 1970-01-01
    相关资源
    最近更新 更多