簡體   English   中英

Angular 使用 takeUntil 進行可觀察銷毀:ngOnDestroy 中缺少.next() 時會發生什么

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

在 Angular 7 組件中,我使用 RxJS takeUntil() 正確取消訂閱可觀察訂閱。

  • ngOnDestroy方法中缺少this.destroy$.next()時會發生什么(參見下面的示例)? 它仍然會正確退訂嗎?
  • ngOnDestroy方法中缺少this.destroy$.complete()時會發生什么(參見下面的示例)? 它仍然會正確退訂嗎?
  • 有什么方法可以強制使用 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將 next 作為發射。 如果只調用了complete()則不會取消訂閱

試試這個:

const a=new Subject();
interval(1000).pipe(takeUntil(a)).subscribe(console.log);
timer(3000).subscribe(_=>a.complete())
  1. this.destroy$仍在 memory 中,不會被垃圾回收
  2. 不是我知道

還請查看此處以避免在使用takeUntil時發生 memory 泄漏。

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

我個人更喜歡在銷毀時明確unsubscribe

this.destroy$.next()觸發 Subject 觸發takeUntil操作符,完成flightService.getAll()訂閱。

this.destroy$.complete()在組件被銷毀時完成destroy$ Subject。

嗨使用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();
    }
}

這是一個更簡單的方法:

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