我希望能够等待Monos列表得到解决,并且在最后一个元素完成后,继续进行另一个异步调用
public Mono<Artist> getArtistInfo(String id) {
//Call API1
Mono<MusicResponse> musisResponseMono = webClientBuilder.build().get().uri(uri + "\"+ id).
retrieve().bodyToMono(MusicResponse.class);
//1.async handler for the first call
return musisResponseMono.flatMap(musicRes ->{
Artist artist = new Artist();
List<Albums> albums =musicRes.getAlbums();
//make mutiple concurrent API calls to API2
albums.stream().forEach( album -> {
webClientBuilder.build().get().uri("API 2 URL").
retrieve().bodyToMono(Covers.class)
.subscribe(cover -> artist.getAlbums().add(cover.getImage()));
});
//call API3 - want to wait untill all API calls 2 are completed
return webClientBuilder.build().get().uri("API3 URL).
retrieve().bodyToMono(Profiles.class).map( profileRes -> artist.setDescription(profileRes.getDescription());
}
}
问题在于API调用3可能会在第二个调用的每个元素都返回之前返回。我想我要寻找的是在Spring Webflux上下文中在Javascipt中等待asycn
答案 0 :(得分:2)
我认为这应该有效。
我们首先获取艺术家并绘制响应。在映射过程中,我们获取每个专辑的封面并获得List<Mono<Cover>>
博克。
然后,我们将它们合并到Flux#merge
中,并在每个Cover
可用时发出它们。这样我们就可以在每次发射doOnNext
并将它们附加到艺术家上。
完成后,我们只需then
并返回艺术家对象。
这些事件链之后,我们可以doOnSuccess
进行第二次提取,并将更多信息附加到Artist
对象。
public Mono<Artist> getArtistInfo(String id) {
return webClient.get()
.uri("/artist")
.retrieve()
.bodyToMono(ArtistResponse.class)
.flatMap(artistResponse -> {
final Artist artist = new Artist();
return Flux.fromIterable(artistResponse.getAlbums())
.parallel(2)
.runOn(Schedulers.parallel())
.map(albums -> webClient.get()
.uri("artist/albums")
.retrieve()
.bodyToMono(Covers.class))
.doOnNext(coversMono -> coversMono
.doOnSuccess(covers -> artist.getAlbums().add(covers)))
.thenReturn(artist);
})
.doOnSuccess(artist -> webClient.get()
.uri("/artist/profile")
.retrieve()
.bodyToMono(Profiles.class)
.doOnSuccess(profiles -> artist.setDescription(profiles.getDescription())));
}
没有运行代码,因此不能保证,但是至少它可以为您提供一些见识,并为您迈出一步。