为何RxJS应用中HTTP请求被发送两次?已用share()仍无效
你遇到的问题核心在于**share()操作符的特性结合Angular模板中async管道的订阅时机**,具体原因如下:
share()的作用是将冷Observable转为热Observable,但仅在存在活跃订阅时共享数据流。对于ajax这类一次性发出值后就完成的Observable,当所有订阅者取消订阅后,新的订阅会重新触发源Observable的执行。- 模板中
*ngIf="users$ | async"是第一个订阅,触发ajax请求。当请求完成、users$发出值后,async管道会因为Observable已完成而自动取消这个订阅。 - 此时
*ngIf条件变为true,开始渲染内部的三个*ngFor,每个*ngFor里的users$ | async都会创建新的订阅。由于之前的订阅已经全部取消,share()没有活跃的共享订阅可以复用,于是会重新触发ajax请求,导致第二次请求发送。
控制器代码
import { Component } from '@angular/core'; import { Observable } from 'rxjs'; import { ajax } from 'rxjs/ajax'; import { map, share } from 'rxjs/operators'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], }) export class AppComponent { users$: Observable<any> = ajax( 'https://jsonplaceholder.typicode.com/users' ).pipe( map((res: any) => res?.response), share() ); }
模板代码
<div *ngIf="users$ | async"> <li *ngFor="let item of users$ | async"> {{ item.name }} </li> <li *ngFor="let item of users$ | async"> {{ item.name }} </li> <li *ngFor="let item of users$ | async"> {{ item.name }} </li> </div>
内容的提问来源于stack exchange,提问作者Sergey
相关产品推荐
相关产品推荐

