我是正确的假设,“ 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毫秒的呼叫已经解决。
答案 0 :(得分:0)
首先,除非有人订阅,否则什么都不会发生。订阅是链中的最后一件事,它将触发所有事件的开始。
您需要了解的第二点是,并行运行某项与无阻塞运行某项的区别。
要解析您的第一张地图,它需要进行其余的调用,然后需要响应才能绘制第二张地图。这两个不会并行运行。
您的responseMono.map
在Mono<Response> responseMono
实际包含某些内容之前无法运行。可以将其视为Promise
,它会在解决应用程序时发出信号。
或者您可以将其视为回调链。
因此,在您的示例中,您正在执行clientRequestHandler.makeAsyncCall()
,但是您将返回Mono<CoverResponse>
的下一个部分responseMono.map
,直到单声道中有CoverResponse
。因此,您的“异步”调用可能是异步的,但由于列表顺序始终在顺序流中,因此仍然遵循列表顺序。
但是map
是一个映射函数。它从盒子中取出东西,对盒子中的东西进行计算,然后返回新值或类型。
使反应性优于其他选项的原因是,当您在需要时间的某个地方进行side effect
远程调用时,正在处理此问题的线程不会徘徊并等待外部请求完成,它将开始做其他事情,例如处理其他请求。
然后,当Mono<Response>
通知系统“盒子中有东西”响应时,则相同的线程或任何其他可用线程将继续处理请求。