如何等待 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())));
}

没有 运行 代码,所以不能保证它,但至少它会给你一些洞察力,并在路上迈出一步。