取消订阅 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 调用? [复制]