如何复用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
相关产品推荐
相关产品推荐

