简体   繁体   English

Angular 使用 takeUntil 进行可观察销毁:ngOnDestroy 中缺少.next() 时会发生什么

[英]Angular Observable destroy with takeUntil: What happens when .next() is missing in ngOnDestroy

In an Angular 7 Component, I use the RxJS takeUntil() to properly unsubscribe on observable subscriptions.在 Angular 7 组件中,我使用 RxJS takeUntil() 正确取消订阅可观察订阅。

  • What happens when the this.destroy$.next() is missing in the method ngOnDestroy (see sample below)?ngOnDestroy方法中缺少this.destroy$.next()时会发生什么(参见下面的示例)? Will it still unsubscribe properly?它仍然会正确退订吗?
  • What happens when the this.destroy$.complete() is missing in the method ngOnDestroy (see sample below)?ngOnDestroy方法中缺少this.destroy$.complete()时会发生什么(参见下面的示例)? Will it still unsubscribe properly?它仍然会正确退订吗?
  • Is there any way to enforce that pattern with takeUntil() to unsubscribe is properly used (eg tslint rule, npm package)?有什么方法可以强制使用 takeUntil() 取消订阅的模式被正确使用(例如 tslint 规则,npm 包)?

@Component({
    selector: 'app-flights',
    templateUrl: './flights.component.html'
})
export class FlightsComponent implements OnDestroy, OnInit {
    private readonly destroy$ = new Subject();

    public flights: FlightModel[];

    constructor(private readonly flightService: FlightService) { }

    ngOnInit() {
        this.flightService.getAll()
            .pipe(takeUntil(this.destroy$))
            .subscribe(flights => this.flights = flights);
    }

    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
}
  1. takeUntil takes next as emission. takeUntil将 next 作为发射。 If only complete() called it won't unsubscribe如果只调用了complete()则不会取消订阅

try this out:试试这个:

const a=new Subject();
interval(1000).pipe(takeUntil(a)).subscribe(console.log);
timer(3000).subscribe(_=>a.complete())
  1. this.destroy$ is still in the memory and won't get garbage collected this.destroy$仍在 memory 中,不会被垃圾回收
  2. Not that i am aware of不是我知道

Please also take a look here to avoid memory leak when using takeUntil .还请查看此处以避免在使用takeUntil时发生 memory 泄漏。

https://medium.com/angular-in-depth/rxjs-avoiding-takeuntil-leaks-fb5182d047ef https://medium.com/angular-in-depth/rxjs-avoiding-takeuntil-leaks-fb5182d047ef

Personally I prefer explicit unsubscribe upon destroy.我个人更喜欢在销毁时明确unsubscribe

this.destroy$.next() triggers the Subject which triggers the takeUntil operator which completes the flightService.getAll() subscription. this.destroy$.next()触发 Subject 触发takeUntil操作符,完成flightService.getAll()订阅。

this.destroy$.complete() completes the destroy$ Subject when component is destroyed. this.destroy$.complete()在组件被销毁时完成destroy$ Subject。

Hi use takeWhile instead of takeUntil .嗨使用takeWhile而不是takeUntil

@Component({
    selector: 'app-flights',
    templateUrl: './flights.component.html'
})
export class FlightsComponent implements OnDestroy, OnInit {
    private readonly destroy$ = new Subject();
    alive = true;
    public flights: FlightModel[];

    constructor(private readonly flightService: FlightService) { }

    ngOnInit() {
        this.flightService.getAll()
            .pipe(takeWhile(() => this.alive))
            .subscribe(flights => this.flights = flights);
    }

    ngOnDestroy() {
        this.alive = false;
        this.destroy$.complete();
    }
}

Here's a simpler approach:这是一个更简单的方法:

private readonly destroy$ = new Subject<boolean>();

...

ngOnDestroy() {
    this.destroy$.next(true);
    this.destroy$.unsubscribe();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM