Web反应式编程-从HTTP客户端的角度来看有哪些优势



让我们假设控制器生成一些具有延迟的随机数的这两种情况:

1)被动弹簧5被动应用:

@GetMapping("/randomNumbers")
public Flux<Double> getReactiveRandomNumbers() {
    return generateRandomNumbers(10, 500);
}
/**
 * Non-blocking randon number generator
 * @param amount - # of numbers to generate
 * @param delay - delay between each number generation in milliseconds
 * @return
 */
public Flux<Double> generateRandomNumbers(int amount, int delay){
    return Flux.range(1, amount)
               .delayMillis(delay)
               .map(i -> Math.random());
}

2)带有DeferredResult:的传统Spring MVC

@GetMapping("/randomNumbers")
public DeferredResult<Double[]> getReactiveRandomNumbers() {
    DeferredResult<Double[]> dr = new DeferredResult<Double[]>();
    CompletableFuture.supplyAsync(() -> {
        return generateRandomNumbers(10, 500);
    }).whenCompleteAsync((p1, p2) -> {
        dr.setResult(p1);
    });
    return dr;
}
/**
 * Blocking randon number generator
 * @param amount - # of numbers to generate
 * @param delay - delay between each number generation in milliseconds
 * @return
 */
public Double[] generateRandomNumbers(int amount, int delay){
    int generated = 0;
    Double [] d = new Double[amount];
    while(generated < amount){
        try {
            Thread.sleep(delay);
        } catch (InterruptedException e) {}
        d[generated] = Math.random();
        generated++;
    }
    return d;
}

从HTTP客户端(浏览器、AJAX请求)的角度来看,这两种场景之间没有任何区别。我的意思是,客户端将等到所有结果都发送出去,并且在整个响应提交之前不会处理它们。

也就是说,尽管spring-web reactive让我们认为它在生成结果时会将结果发回,但事实并非如此,在生成所有数字之前,客户端将无法处理结果。

让客户端完全响应的简单方法是使用WebSockets。

那么,除了很酷的东西(比如漂亮的语义、组合…)之外,考虑到浏览器HTTP请求不是被动的,相当于使用传统的DeferredResult,使用SpringWebReactive有什么意义

存在差异,所以让我尝试将其分解。

对于DeferredResult<Double[]>返回值,显然必须先准备好数组,然后才能将值写入响应。

Spring Web Reactive确实在Flux<Double>可用时编写每个单独的值。现在,从浏览器的角度来看,您可能看不到实际的差异,因为在收到完整的JSON数组之前,它不会给您完整的JSON阵列。

这更多的是一个如何流式传输到浏览器的问题?例如,如果添加"Accept: text/event-stream"作为请求标头,则可以将每个double作为浏览器中的单个事件使用。因此,服务器有能力做到这一点并高效地完成这一点。

相关内容

  • 没有找到相关文章

最新更新