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

Angular12中如何让RxJS Observable在另一个Observable值为true后执行

问题描述

我正在使用Angular 12和RxJS开发一款电商类应用,创建了一个分类服务,通过GraphQL从服务端拉取分类数据并解析,方便站点其他模块调用。
目前遇到的问题是:如果用户直接进入使用了分类服务的页面,由于GraphQL请求尚未返回数据,服务会返回空响应。因此我计划创建一个isInitialized可观察对象,在数据加载处理完成后将其值设为true,让其他函数感知到服务已可正常使用。
服务核心代码如下:

@Injectable({
  providedIn: 'root'
})
export class ProductCategoriesService {

  adminQueryProductCategories=this.gql.adminQueryProductCategories();

  isInitialized: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

  constructor(private gql: GraphqlService) {
    this.adminQueryProductCategories.valueChanges.subscribe(({data})=>{
      this.categories=data.adminQueryProductCategories;
      this.parseCategoryTree(this.categories);
      this.isInitialized.next(true);
    });
  }

从productCategories$可观察对象拉取数据的函数实现如下:

getCategoryTitleByLabel(label: string): Observable<ProductCategory[]> {
  return this.productCategories$.pipe(map((pc: ProductCategory[]) => pc.filter(p => p.category_label === label)));
}

我需要让上述函数返回的Observable仅在isInitialized可观察对象的值为true后才执行,请问有什么解决方案?

更新说明1

整体需求为:用户浏览分类页面时,需要校验分类是否存在,不存在则路由到首页。首次加载时由于GraphQL请求尚未完成,用户总是会被直接路由到首页,相关代码如下:

ngOnInit(): void {
  this.route.params.subscribe(params => {
    this.label = params['category'];
    this.pcService.getCategoryTitleByLabel(this.label).subscribe((data)=>{
      if (data.length !== 1) {
        this.router.navigate(['/']).finally(()=>{
          //TODO: popup of some sort ?
        });
      } else {

更新说明2

productCategories$的实现如下:

private productCategories = new BehaviorSubject<ProductCategory[]>([]);
get productCategories$(): Observable<ProductCategory[]> {
  return this.productCategories;
}
最终解决方案

将原有的BehaviorSubject替换为ReplaySubject即可解决问题,无需修改按标签查询分类的函数。
原有实现:

private productCategories = new BehaviorSubject<ProductCategory[]>([]);
get productCategories$(): Observable<ProductCategory[]> {
  return this.productCategories;
}

修改后实现:

productCategories$ = new ReplaySubject<ProductCategory[]>();

修改完成后即可生效,原有查询函数无需调整:

getCategoryTitleByLabel(label: string): Observable<ProductCategory[]> {
  return this.productCategories$.pipe(map((pc: ProductCategory[]) => pc.filter(p => p.category_label === label)));
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:36:04