在Angular 9中同步(即)按顺序进行N次api调用的最佳方法
Posted
技术标签:
【中文标题】在Angular 9中同步(即)按顺序进行N次api调用的最佳方法【英文标题】:Best way to make N-number of api calls in Angular 9 synchronously (i.e) sequentially 【发布时间】:2021-06-06 23:42:22 【问题描述】:我有一个 API 调用的服务方法,方法如下:-
getUsers(id)
return this.http.get(`$env.apiURL/id`)
现在我需要为数组中存在的用户列表调用此方法,如下所示:-
userId=[1,2,3,4,5,6,7,8,9]
我需要通过以下方式获取所有 API 调用结果并打印出来:-
let user1= this.http.get(baseurl+'users/userId[1]');
let user2= this.http.get(baseurl+'users/userId[2]');//In the similar way I have 10 values
forkJoin([user1, user2]).subscribe(results =>
// results[0] is our user1
// results[1] is our user2
);
但以上述方式,我无法按顺序进行 API 调用,即所有 API 调用同步进行,这不是我的用例。
是否有任何最好的方法可以按顺序进行上述 n(可变用户数)API 调用? 注意:-我还有另一种情况,可以在每次 API 调用后保持 500 毫秒的延迟。我尝试使用
pipe(throttletime(500)) //this i added after forkJoin operation
但是所有的 API 调用同时进行
【问题讨论】:
【参考方案1】:您可以通过使用concatmap
运算符以特定顺序发出请求来实现此目的。
请参考 => https://rxjs-dev.firebaseapp.com/api/operators/concatMap
【讨论】:
我想迭代一个数组,然后为每次迭代调用一个 api 调用可能使用 concat Map 进行迭代【参考方案2】:有很多方法可以完成这项任务。以下是其中的几个:
方法一:
users$ = from(this.userIds).pipe(
concatMap(id => this.getUser(id)),
take(this.userIds.length),
toArray()
);
步骤:
from
- 创建单独发出每个数组元素的 observable
concatMap
- 将 ID 映射到 observable,订阅它并发出结果。一次只允许一个getUser(id)
订阅(同步)
take
- 指示我们的流在完成之前需要多少个值
toArray
- 收集排放物并在完成时将它们作为数组发射
方法二:
users$ = from(this.userIds).pipe(
concatMap(id => this.getUser(id)),
scan((all: User[], user) => ([...all, user]), []),
);
步骤:
from
concatMap
scan
- 将排放累积到单个数组中。每次收到新值时发出
其中任何一个都应该可以正常工作,但行为有所不同。在所有单独的调用完成后,方法 #1 只会发出一次。方法 #2 将为每次发射发射一次。 (如果只需要一个发射,reduce
可以代替)
查看此StackBlitz,了解两种方法的输出差异。
【讨论】:
为什么不在方法1中使用reduce
操作符而不是toArray
?
@MichaelD - 我在方法 2 的子文本中提到了reduce
。当然可以,但我认为toArray()
更易于阅读。如果 toArray
只是 reduce
的一个特定用例,我不会感到惊讶 :-)
这正是it is。
哈哈...不错!我懒得去查了。 :-)以上是关于在Angular 9中同步(即)按顺序进行N次api调用的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Global Round 9 E. Inversion SwapSort