angular rxjs操作符 shareReply(1),处理并发http请求,把请求的key的observable 缓存到map,shareReply(1) 会缓存最近一次的result,可以避免同时并发请求多次服务。
- 缺点:observable 可观察对象的引用会一直存在内存中,有内存溢出的可能性。
- 可以通过weakmap 弱引用map,内存需要时会释放内存,或者使用takeUtil 取消引用。
Sure, another approach to handling concurrent calls to the isAllow method without debouncing or locking is to adjust the way you manage the cache. Instead of directly caching the result of each request, you can cache the observable itself, effectively sharing the observable among all callers. This way, if multiple components call isAllow with the same parameters simultaneously, they’ll all receive the same observable, avoiding multiple HTTP requests for the same data.
export class StaffRoleService{
private roleCache = new Map<string, Observable<boolean>>();
public isAllow(userId: number, roleDomain: UserRoleDomain): Observable<boolean> {
const key = userId + ":" + roleDomain;
if (this.roleCache.has(key)) {
return this.roleCache.get(key);
} else {
const observable = this.http.get<boolean>(this.getBaseUrl() + '/staffId/' + userId + '/isAllow?userRoleDomainId=' + roleDomain).pipe(
tap((re: boolean) => {
}),
catchError((error) => {
return of(false);
}),
// Use shareReplay to share the observable among multiple subscribers and cache its result
shareReplay(1)
);
this.roleCache.set(key, observable);
return observable;
}
}
}
n this modification:
We store observables in the cache instead of the actual result of the HTTP request.
If multiple components call isAllow with the same parameters simultaneously, they’ll all receive the same observable from the cache.
The shareReplay(1) operator ensures that the result of the observable is shared among all subscribers and cached, so subsequent subscribers receive the cached result without triggering additional HTTP requests.
This approach avoids the need for debouncing or locking and ensures that each unique combination of userId and roleDomain triggers only one HTTP request, regardless of how many components call isAllow simultaneously with the same parameters.