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

时间:2016-08-04 07:36:19

标签: spring rx-java reactive-programming project-reactor

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

1)Reactive Spring 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)传统的Spring MVC与DeferredResult

@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请求)的角度来看,两种方案之间没有任何区别。我的意思是客户端将等待所有结果发送,并且在提交整个响应之前不会处理它们。

也就是说,虽然弹簧网反应使我们认为它在生产过程中将结果发回,实际上它不会发生这种情况,客户端将无法处理结果数字已经生成。

使客户端完全被动的直接方法是使用WebSockets。

所以,除了很酷的东西(比如很好的语义,组合......),使用Spring Web Reactive的意义是什么,考虑到浏览器的HTTP请求不是被动的,等同于使用传统的DeferredResult吗

1 个答案:

答案 0 :(得分:15)

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

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

Spring Web Reactive会在Flux<Double>可用时写出每个值。现在从浏览器的角度来看,您可能看不到实际的差异,因为它不会为您提供完整的JSON数组,直到它完全收到。

这是一个如何流入浏览器的问题?例如,如果您将"Accept: text/event-stream"添加为请求标头,则可以将每个double作为浏览器中的单个事件使用。因此,服务器执行此操作并有效执行此操作的能力就在那里。