You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何RxJS应用中HTTP请求被发送两次?已用share()仍无效

RxJS 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 12:15:17