取消订阅 Angular 中的 observable

Posted

技术标签:

【中文标题】取消订阅 Angular 中的 observable【英文标题】:Unsubscribing to an observable in Angular 【发布时间】:2018-12-12 18:11:23 【问题描述】:

当我按下按钮时,我会从服务器获取特定车辆的信息。这是通过订阅 observable 来完成的。当我再次按下同一个按钮时,我想取消订阅我正在查看的当前“vehicleDetail”(以避免内存泄漏),因为我正在检查另一辆车的新数据。

我正在使用 VehicleDetail 类,具有以下属性:

export class VehicleDetail 
  id: number;
  name: string;
  alarm: Alarms[] | null;
  signalinfo: SignalInfo[];
  position: Position | null;

这是我的 .service.ts 中的代码:

    getVehicleDetail(id: number): Observable<VehicleDetail> 
        const url = `$this.vehiclesUrl/$id/$'detail'`;
        return this.http.get<VehicleDetail>(url).pipe(
          tap(_ => this.log(`fetched vehicle detail id=$id`)),
          catchError(this.handleError<VehicleDetail>(`getVehicledetail id=$id`))
        );
      

在我的 .component.ts 中:

import  Component, OnInit  from '@angular/core';
import  Observable, Subject  from 'rxjs';
import  takeUntil  from 'rxjs/operators';
import * as Leaflet from 'leaflet';

import  VehicleService  from '../vehicle.services';
import  VehicleDetail  from '../models/vehicle-detail';

.........

vehicleDetail: VehicleDetail;
private unsubscribe$ = new Subject();

.........



  getVehicleDetail(): Observable<VehicleDetail> 
    const details = this.vehicleService
      .getVehicleDetail(this.vehicleService.vehicleId);

    details.takeUntil(this.unsubscribe$).subscribe(data => 
      this.vehicleDetail = data;
    );
    return details;
  

updateInfo(item): void 
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
    this.vehicleService.vehicleId = item;
    console.log(this.vehicleService.vehicleId);
    this.getVehicleDetail().takeUntil(this.unsubscribe$).subscribe(() => 
      if (this.vehicleDetail.position) 
        this.setMap();
        return;
      
      this.map.flyTo(new Leaflet.LatLng(50.7089, 10.9746), 4, 
        animate: true,
        duration: 4
      );
    );
  

我得到的错误来自 takeUntil,它说:

错误 TS2339:类型上不存在属性“takeUntil” “可观察”。

我在这里做错了什么?

【问题讨论】:

如果你使用的是 RxJS 6,你需要migrate。 是什么让你认为不退订可能会导致内存。泄漏? @Jota.Toledo 同时拥有数百个订阅不是一个很大的缺陷吗? 【参考方案1】:

您不创建套接字的 http 请求不需要取消订阅 observable,它会最终确定为已完成状态。为什么不直接从 updateInfo 调用服务,并使用您收到的 id 作为参数?

updateInfo(vehicleId: number): void 
    this.vehicleService.getVehicleDetail(vehicleId)
     .subscribe((data) => 
       this.vehicleDetail = data;
       if (this.vehicleDetail.position) 
         this.setMap();
         return;
       
       this.map.flyTo(new Leaflet.LatLng(50.7089, 10.9746), 4, 
         animate: true,
         duration: 4
       );
     );

【讨论】:

take(1) 在你描述的情况下是一个 noop,因为 observables 本质上只会发射一次 你是对的,http 完成了 observable,不需要 take(1)。为避免混淆而编辑。

以上是关于取消订阅 Angular 中的 observable的主要内容,如果未能解决你的问题,请参考以下文章

我应该取消订阅根 Angular 组件中的 observables 吗?

我们是不是需要取消订阅 Angular 中的 http 调用? [复制]

如果已经使用相同的请求运行,则取消订阅/取消 Angular 4 中的现有 HTTP/XHR 调用

组件 ngOnInit 中的 Angular 订阅

我需要手动取消订阅吗? - Angular 8 [重复]

Angular HttpClient取消订阅[重复]