映射和Mono \ Flux订阅之间的区别?

时间:2019-07-04 00:45:13

标签: reactive-programming spring-webflux

我是正确的假设,“ map”本质上可以是带有返回类型的“ subscribe”。当承诺得到解决时,它们似乎都被异步调用了?

例如,如果我同时分派3个Async调用的列表,将以下面的方式应用map操作会阻塞吗?

 Flux.merge(albums.stream().map(album -> {

        Mono<CoverResponse> responseMono  = clientRequestHandler.makeAsyncCall()

           //2.call and handler for async call
           return responseMono
                   .map(response -> processResponse());

       }).collect(Collectors.toList())).then(Mono.just(monoResponse));

在上面的代码段中,每个map操作都会被阻塞吗?如果说,第一个调用需要5毫秒才能返回,而其他每个调用都需要2毫秒才能返回,我们是否要等待3ms + 2ms + 2m = 7ms进行enitre操作?距第一个呼叫解决后仅3毫秒,到那时为止2毫秒的呼叫已经解决。

1 个答案:

答案 0 :(得分:0)

首先,除非有人订阅,否则什么都不会发生。订阅是链中的最后一件事,它将触发所有事件的开始。

您需要了解的第二点是,并行运行某项与无阻塞运行某项的区别。

要解析您的第一张地图,它需要进行其余的调用,然后需要响应才能绘制第二张地图。这两个不会并行运行。

您的responseMono.mapMono<Response> responseMono实际包含某些内容之前无法运行。可以将其视为Promise,它会在解决应用程序时发出信号。

或者您可以将其视为回调链。

因此,在您的示例中,您正在执行clientRequestHandler.makeAsyncCall(),但是您将返回Mono<CoverResponse>的下一个部分responseMono.map,直到单声道中有CoverResponse 。因此,您的“异步”调用可能是异步的,但由于列表顺序始终在顺序流中,因此仍然遵循列表顺序。

但是map是一个映射函数。它从盒子中取出东西,对盒子中的东西进行计算,然后返回新值或类型。

使反应性优于其他选项的原因是,当您在需要时间的某个地方进行side effect远程调用时,正在处理此问题的线程不会徘徊并等待外部请求完成,它将开始做其他事情,例如处理其他请求。

然后,当Mono<Response>通知系统“盒子中有东西”响应时,则相同的线程或任何其他可用线程将继续处理请求。