Reactor - 如何避免递归?
Reactor - How to avoid recursion?
使用 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());
});
}
要替换递归,您可以使用 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。
使用 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());
});
}
要替换递归,您可以使用 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。