如何等待 List<Mono> 得到解析?
How do I wait for a List<Mono> to get resolved?
我希望能够等待 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 可能 return 在第二次调用的每个元素被 returned 之前。我想我正在寻找的是 Spring Webflux
上下文中 Javascipt 中的 asycn await 之类的东西
我认为这应该可行。
我们首先获取艺术家并映射响应。在映射期间,我们获取每个专辑封面并获得一个 List<Mono<Cover>>
bock。
然后我们将它们合并到一个 Flux#merge
中,当它们可用时将发出每个 Cover
。所以我们可以在每个上发出 doOnNext
并将它们附加到艺术家。
完成后,我们只需要 then
和 return 艺术家对象。
在这些事件链之后,我们可以 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())));
}
没有 运行 代码,所以不能保证它,但至少它会给你一些洞察力,并在路上迈出一步。
我希望能够等待 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 可能 return 在第二次调用的每个元素被 returned 之前。我想我正在寻找的是 Spring Webflux
上下文中 Javascipt 中的 asycn await 之类的东西我认为这应该可行。
我们首先获取艺术家并映射响应。在映射期间,我们获取每个专辑封面并获得一个 List<Mono<Cover>>
bock。
然后我们将它们合并到一个 Flux#merge
中,当它们可用时将发出每个 Cover
。所以我们可以在每个上发出 doOnNext
并将它们附加到艺术家。
完成后,我们只需要 then
和 return 艺术家对象。
在这些事件链之后,我们可以 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())));
}
没有 运行 代码,所以不能保证它,但至少它会给你一些洞察力,并在路上迈出一步。