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

如何复用Angular的subscribe函数?避免重复订阅的优化方案

解决方案:无需重复订阅,复用RxJS请求逻辑

你完全不用重复订阅或复制逻辑,以下是几种更简洁的优化方案:

方案1:让carregaDados返回Observable,复用基础逻辑

把carregaDados改成返回Observable,用tap操作符处理通用的成功/错误逻辑,这样其他函数可以直接订阅这个Observable,再追加额外逻辑:

import { tap, Observable } from 'rxjs';

// 修改carregaDados,返回Observable
carregaDados(): Observable<Result> {
  return this.dataService.getData().pipe(
    tap({
      next: (res: Result) => {
        if (!res.success) {
          this.errors.set([res.errors[0]?.message || "Erro desconhecido"]);
        } else {
          this.conectar(this.dataService.data);
          this.dataFilters = this.dataService.geraObjFiltros();
          this.dateTimeUpdatelabel.set(this.dataService.dateTimeUpdateLabel);
        }
      },
      error: (err) => {
        console.log('Erro:', err.message);
        this.errors.set([err.message]);
      }
    })
  );
}

// 复用carregaDados的逻辑,添加额外操作
atualizarGrid() {
  const estadoGrid = this.datasource.estadoCorrente;
  this.carregaDados().subscribe({
    next: () => {
      // 只写当前函数特有的逻辑
      const dataFiltered = this.dataService.goFilterFinal();
      this.conectar(dataFiltered);

      this.datasource.ordenacao = estadoGrid.ordenacao;
      this.datasource.tamanhoPagina = estadoGrid.tamanhoPagina;
      this.datasource.pagina = estadoGrid.pagina;
      
      console.log(this.datasource.estadoCorrente);
    }
  });
}

方案2:抽离通用处理函数,避免代码复制

如果不想修改carregaDados的返回类型,可以把重复的成功/错误逻辑抽成单独方法,在需要的地方直接调用:

// 抽离通用成功处理逻辑
handleDataSuccess(res: Result) {
  if (!res.success) {
    this.errors.set([res.errors[0]?.message || "Erro desconhecido"]);
  } else {
    this.conectar(this.dataService.data);
    this.dataFilters = this.dataService.geraObjFiltros();
    this.dateTimeUpdatelabel.set(this.dataService.dateTimeUpdateLabel);
  }
}

// 抽离通用错误处理逻辑
handleDataError(err: any) {
  console.log('Erro:', err.message);
  this.errors.set([err.message]);
}

// 原carregaDados调用抽离的方法
carregaDados() {
  this.dataService.getData().subscribe({
    next: this.handleDataSuccess.bind(this),
    error: this.handleDataError.bind(this)
  });
}

// 另一个函数复用通用逻辑,追加额外操作
atualizarGridAnotherSubscribe() {
  this.dataService.getData().subscribe({
    next: (res: Result) => {
      this.handleDataSuccess(res);
      // 当前函数特有的逻辑
      const estadoGrid = this.datasource.estadoCorrente;
      const dataFiltered = this.dataService.goFilterFinal();
      this.conectar(dataFiltered);

      this.datasource.ordenacao = estadoGrid.ordenacao;
      this.datasource.tamanhoPagina = estadoGrid.tamanhoPagina;
      this.datasource.pagina = estadoGrid.pagina;
    },
    error: this.handleDataError.bind(this)
  });
}

补充:让async/await生效的方法

你之前用await this.carregaDados()无效,是因为carregaDados没有返回Promise。可以用firstValueFrom把Observable转成Promise,适配async/await:

import { firstValueFrom } from 'rxjs';

async carregaDados(): Promise<Result> {
  try {
    const res = await firstValueFrom(this.dataService.getData());
    // 通用处理逻辑
    if (!res.success) {
      this.errors.set([res.errors[0]?.message || "Erro desconhecido"]);
    } else {
      this.conectar(this.dataService.data);
      this.dataFilters = this.dataService.geraObjFiltros();
      this.dateTimeUpdatelabel.set(this.dataService.dateTimeUpdateLabel);
    }
    return res;
  } catch (err) {
    console.log('Erro:', err.message);
    this.errors.set([err.message]);
    throw err;
  }
}

// 现在await可以正常等待请求完成
async atualizarGrid() {
  const estadoGrid = this.datasource.estadoCorrente;
  await this.carregaDados();
  
  const dataFiltered = this.dataService.goFilterFinal();
  this.conectar(dataFiltered);

  this.datasource.ordenacao = estadoGrid.ordenacao;
  this.datasource.tamanhoPagina = estadoGrid.tamanhoPagina;
  this.datasource.pagina = estadoGrid.pagina;
  
  console.log(this.datasource.estadoCorrente);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:40:22