Angular项目云函数被多次重复调用问题如何排查解决?
问题触发原因
核心原因为RxJS中Cold Observable的单播特性:Cold Observable 每被订阅一次,就会完整执行一次上游的生产逻辑,你当前场景的上游逻辑就是调用云函数拉取数据,因此订阅次数等于云函数调用次数。
你场景中的3次订阅来源分别为:
- HTML模板中直接对
profileList$使用async管道,触发第一次订阅 - 派生数据
fieldsToSearch$基于profileList$创建,触发第二次订阅 - HTML模板中对
fieldsToSearch$使用async管道,间接触发对profileList$的第三次订阅
你尝试使用的take(1)仅能控制单个订阅的返回次数,无法解决多订阅重复触发上游逻辑的问题,因此无效。
修复方案
通过多播操作符将profileList$从单播的Cold Observable转为支持多订阅共享结果的Hot Observable即可,推荐使用shareReplay操作符,它会缓存上游返回的最新结果,所有下游订阅都共享同一份缓存,不会重复触发云函数调用:
import { shareReplay } from 'rxjs'; this.profileList$ = this.usersService.profileList(this.route.snapshot.paramMap.get('groupId')!).pipe( tap(() => console.log('call')), catchError(() => { this.toastrService.danger('You do not have permission to view this group', 'Error'); return of([]); }), // 新增多播配置 shareReplay({ bufferSize: 1, refCount: true }) );
配置说明:
bufferSize: 1表示仅缓存最近1次返回的结果,所有新订阅直接拿到缓存数据refCount: true表示当所有下游订阅都销毁时,自动释放当前流的资源,避免内存泄漏
如果你的业务场景不需要缓存历史结果,也可以使用share()操作符替代shareReplay。
内容的提问来源于stack exchange,提问作者Rodrigo Assis Neves
相关产品推荐
相关产品推荐

