【问题标题】:Angular Observable destroy with takeUntil: What happens when .next() is missing in ngOnDestroy使用 takeUntil 进行 Angular Observable 销毁:ngOnDestroy 中缺少 .next() 时会发生什么
【发布时间】:2020-02-14 00:14:27
【问题描述】:

在 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();
    }
}

【问题讨论】:

标签: angular rxjs observable unsubscribe


【解决方案1】:
  1. takeUntil 将 next 作为发射。如果只有complete() 调用它不会取消订阅

试试这个:

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

也请看这里以避免使用takeUntil时出现内存泄漏。

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

我个人更喜欢在销毁时使用明确的unsubscribe

【讨论】:

    【解决方案2】:

    这里有一个更简单的方法:

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

    【讨论】:

    • 您可能不需要在主题上声明类型
    【解决方案3】:

    您好,请使用 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();
        }
    }
    

    【讨论】:

      【解决方案4】:

      this.destroy$.next() 触发 Subject 触发 takeUntil 运算符完成 flightService.getAll() 订阅。

      this.destroy$.complete() 在组件被销毁时完成 destroy$ 主题。

      【讨论】:

        猜你喜欢
        • 2018-02-04
        • 2016-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多