Angular中使用async绑定相较于映射到组件属性有哪些优势?
服务调用返回页面渲染数据时,async绑定相比直接赋值组件属性的优势分析
两种实现方案对比
方案1:直接映射到组件属性
组件&服务代码
// component event: any; // ngOnInit() this.eventService.getEvent(this.id).pipe(take(1)).subscribe(response => { this.event = response; }, error => { console.log(error); }); // service getEvent(id: number): Observable<any> { return this.http.get<any>(this.baseUrl + 'events/' + id); }
模板代码
<div>{{event.title}}</div> <div>{{event.date}}</div>
方案2:async管道绑定
组件&服务代码
// component event$: Observable<any> = of(undefined); // ngOnInit this.event$ = this.eventService.getEvent(this.id).pipe( take(1), catchError(error => { console.log(error); return throwError(error); }) ); // service getEvent(id: number): Observable<any> { return this.http.get<any>(this.baseUrl + 'events/' + id); }
模板代码
<div>{{(event$ | async).title}}</div> <div>{{(event$ | async).date}}</div>
async绑定的核心优势
- 自动管理订阅生命周期,避免内存泄漏:async管道会在组件销毁时自动取消订阅,不需要手动编写
unsubscribe逻辑,哪怕请求还没返回组件就被销毁,也不会产生悬空订阅泄漏内存。而手动订阅场景下,哪怕用了take(1),极端场景下依然有概率出现内存泄漏风险,还要额外编写销毁逻辑徒增工作量。 - 减少样板代码,降低出错概率:不需要手动声明临时变量存储响应结果,也不需要写
subscribe回调做赋值操作,组件代码更简洁,也避免了赋值逻辑写错、漏写的问题。 - 天然适配响应式编程范式:后续如果要对数据流做防抖、节流、过滤、格式转换等操作,只需要在Observable的pipe链里加操作符即可,不需要修改后续的赋值、渲染逻辑,数据流链路更清晰,维护成本更低。
- 适配OnPush变更检测策略:如果组件开启了OnPush变更检测优化,async管道在拿到新值时会自动标记组件为需要重绘,不需要手动触发变更检测,不会出现值更新了视图没刷新的问题。
async绑定优化建议
当前示例中多次使用| async会触发多次重复订阅,甚至发起多次重复请求,建议用ngIf别名优化模板,仅订阅一次即可:
<ng-container *ngIf="event$ | async as event"> <div>{{event.title}}</div> <div>{{event.date}}</div> </ng-container>
内容的提问来源于stack exchange,提问作者chuckd
相关产品推荐
相关产品推荐

