Reactor - 如何避免递归?

时间:2021-02-10 09:11:06

标签: java spring-webflux project-reactor spring-webclient

使用 spring WebFlux,我想逐个发送 HTTP 请求,直到响应满足特定条件。我还需要收集所有回复。在阻塞的世界中,解决方案是这样的:

List<String> responses = new ArrayList<>();
String lastResponse;
do {
  lastResponse = webClient.get()
    .uri(uri)
    .retrieve()
    .bodyToMono(String.class)
    .block();
  responses.add(lastResponse);
} while(!finished(lastResponse));

如何在不阻塞的情况下实现这一点?

注意:递归有一个天真的解决方案,但我正在寻找一种更优雅的方法:

private List<String> collectRemaining() {
  return webClient.get()
    .uri(uri)
    .retrieve()
    .bodyToMono(String.class)
    .flatMap(response -> {
      if(finished(response)) {
        return List.of(response);
      }
      return collectRemaining().flatMap(remaining ->
          Stream.concat(Stream.of(response), remaining.stream()).collect(Collectors.toList());
    });
}

1 个答案:

答案 0 :(得分:1)

要替换递归,您可以使用 expand() 运算符,它可以根据前一个元素生成下一个元素。它通常用于实现分页逻辑。所以像下面这样的东西可以工作:

webClient.get()
        .uri(uri)
        .retrieve()
        .bodyToMono(String.class)
        .expand(response -> {
            if (finished(response)) {
                return Mono.empty();
            }
            return webClient.get()
                    .uri(uri)
                    .retrieve()
                    .bodyToMono(String.class);
        }).collectList();

灵感来自this article

相关问题