Angular RxJS如何订阅父Observable派生的子Observable且不重复触发AJAX请求
默认情况下RxJS的冷Observable每接收一次订阅,就会重新执行一次内部的生产逻辑。你当前的代码中title$和value$各自通过async管道订阅,相当于对父Observableresponse$发起了两次独立订阅,因此会触发两次AJAX请求。
下面是两种常用的解决方案:
方案1:使用shareReplay多播父Observable结果
在父Observable后追加shareReplay(1)操作符,实现多播的同时缓存最新的响应结果,所有派生的子Observable订阅时都会直接复用缓存的响应,不会重复发起请求。
修改后的代码示例:
// 需提前从rxjs/operators导入对应操作符 import { shareReplay, pluck } from 'rxjs/operators'; @Component({ selector: 'my-app', template: ` <h3>{{ title$ | async }}</h3> <p>{{ value$ | async }}</p> `, }) export class AppComponent implements OnInit { public response$: Observable<Response>; public title$: Observable<string>; public value$: Observable<string>; constructor(private fakeAjaxService: FakeAjaxService) {} ngOnInit(): void { // 调用主AJAX请求后追加shareReplay多播并缓存结果 this.response$ = this.fakeAjaxService.request().pipe( shareReplay(1) ); // 派生逻辑无需修改 this.title$ = this.response$.pipe(pluck('title')); this.value$ = this.response$.pipe(pluck('value')); } }
shareReplay(1)表示缓存最近1次的返回结果,就算后续有新的订阅也能直接拿到已返回的响应,非常适配HTTP请求这类单次返回值的场景。
方案2:模板层只订阅一次父Observable
无需修改TS代码,直接调整模板,只用一次async订阅父Observable并将结果存为模板变量,后续直接读取变量的字段即可:
<ng-container *ngIf="response$ | async as response"> <h3>{{ response.title }}</h3> <p>{{ response.value }}</p> </ng-container>
这种方案省去了单独派生title$和value$的步骤,更简洁直观。
内容的提问来源于stack exchange,提问作者synthet1c
相关产品推荐
相关产品推荐

