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

RxJS中BehaviorSubject结合switchMap刷新后无数据问题排查

问题分析与解决

代码文件

app.component.ts

import { Component, OnInit } from '@angular/core';
import { of } from 'rxjs';
import { TestService } from './test.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  posts = [
    { id: 1, name: 'chethan' },
    { id: 2, name: 'rohan' },
    { id: 3, name: 'sai' },
    { id: 4, name: 'yashas' },
  ];

  constructor(private readonly testService: TestService) {}

  getPosts() {
    return of(this.posts);
  }

  ngOnInit(): void {
    this.testService.myData$.subscribe((data) => {
      console.log('from mydata');
      console.log(data);
    });

    // this.testService.mysecondData$.subscribe((data) => {
    //   console.log('from secondata');
    //   console.log(data);
    // });

    this.testService.refresh();
    this.testService.emitProduct(3);
  }
}

test.service.ts

import { Injectable } from '@angular/core';
import {
  BehaviorSubject,
  map,
  Subject,
  switchMap,
  switchMapTo,
  tap,
} from 'rxjs';

@Injectable({
  providedIn: 'root',
})
export class TestService {
  private refreshSubject = new Subject<void>();
  refresh$ = this.refreshSubject.asObservable();

  private productSubject = new BehaviorSubject<number>(1);
  product$ = this.refreshSubject.asObservable();

  mysecondData$ = this.product$.pipe(
    tap(() => console.log('coming to mysecondata')),
    map(() => 5)
  );

  myData$ = this.refresh$.pipe(
    tap(() => console.log('myData before switchmap got refresh pipe')),
    switchMap(() => this.mysecondData$),
    tap(() => console.log('myData after switchmap bypassed refresh pipe'))
  );

  emitProduct(data: number) {
    this.productSubject.next(data);
  }

  refresh() {
    this.refreshSubject.next();
  }
}

问题描述

调用refresh()后,预期myData$会切换到mysecondData$并输出值5,但实际未获取到product$的发射值;即使在ngOnInit中订阅testService.product$,调用productSubject.next()方法后也无法获取数据,请问原因是什么?

问题原因与修复

核心错误出在test.service.ts的product$定义上:
你把product$错误赋值为this.refreshSubject.asObservable(),但它本该和你创建的productSubject绑定。这直接导致两个关键问题:

  1. 调用emitProduct()更新productSubject时,product$完全接收不到任何数据——因为它和productSubject没有任何关联;
  2. mysecondData$依赖product$,但现在product$只有在调用refresh()时才会触发,和productSubject的更新彻底脱节,自然没法得到预期输出。

修复步骤

修改test.service.ts中product$的定义,把它和productSubject绑定:

private productSubject = new BehaviorSubject<number>(1);
// 替换原来的refreshSubject为productSubject
product$ = this.productSubject.asObservable();

修复后,调用refresh()时,myData$会通过switchMap切换到mysecondData$,而mysecondData$依赖的product$会因为productSubject的初始值或emitProduct()的调用发射数据,最终就能输出预期的5。

内容的提问来源于stack exchange,提问作者Chethan B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 22:10:27