我是棱角分明的新人,过去几周开始学习。 我有这个包含noteId和userId的注释列表,使用UserId我需要调用另一个服务,它返回用户名。
ngOnInit() {
this.items.forEach(element => {
this.userService.loadByUserId(element.UserId)
.subscribe(res => element.Name = res.Name) })
}
loadByUserId包含调用User API的代码。
我正在寻找降低UserAPI负载的方法,因为this.items的数量非常庞大。
angular是否提供了一种方法,以便我可以存储先前的请求响应,并在触发第二个请求之前检查对象。对于userId
请求较高的服务器,最终游戏不会超载我试图实现的基本上是在发送请求之前创建一个存储响应的列表,在if else中,我检查列表是否包含用户ID,名称组合,如果不是从列表返回,或者发送请求服务器。
上述方法的问题在于循环只是在其上执行或迭代100(假设?)记录,并且不等待loadByUserId方法返回响应。
请使用await / observables方法建议以角度实现此方法的最佳方法
我尝试实现此功能,但它不会发送用户API请求。
loadByUserGuid(userId: string): Observable<any> {
return this._api.get('User/' + userId).map(res => {
return res;
});
}
Observable.from(this.items).concatMap(element => this.userService.loadByUserGuid(element.UserId).do(res => element.Name = res.Name)).subscribe(() => { });
我们的想法是缓存/存储User API的响应,以避免发送多个请求
答案 0 :(得分:1)
显而易见的答案是更改api以公开可以加载多个用户的loadByIDs
方法。
如果无法做到这一点,您可以将请求与并发限制合并(在此示例中设置为10):
Observable.from(items)
.mergeMap(element =>
this.userService
.loadByUserId(element.UserId)
.do(res => element.Name = res.Name),
10) //at most 10 requests in the same time
.subscribe(() => {}); //start doing the jobs
如果您想按顺序执行此操作,可以使用concatMap
等待上一个请求完成,然后再开始新的请求:
Observable.from(items)
.concatMap(element =>
this.userService
.loadByUserId(element.UserId)
.do(res => element.Name = res.Name))
.subscribe(() => {}); //start
答案 1 :(得分:0)
我最终使用Map来解决此问题,这就像C#词典一样。 Map返回一个可以订阅的Observable对象,从而使循环执行等待响应,然后迭代到下一个元素。
cache = new Map<string, Observable<any>>();
loadByUserId(userId: string) {
if (userId != null) {
if (!this.cache.has(userId)) {
this.cache.set(userId, this._api.get('User/' + userId).pipe().shareReplay(1));
}
return this.cache.get(userId);
}
return Observable.empty();
}