英文:
Mono class in Java: what is, and when to use?
问题
我有以下代码:
    import org.springframework.http.MediaType;
    import org.springframework.stereotype.Component;
    import org.springframework.web.reactive.function.BodyInserters;
    import org.springframework.web.reactive.function.server.ServerRequest;
    import org.springframework.web.reactive.function.server.ServerResponse;
    import reactor.core.publisher.Mono;
    @Component
    public class GreetingHandler {
        public Mono<ServerResponse> hello(ServerRequest request) {
            return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
            .body(BodyInserters.fromValue("Hello Spring!"));
        }
    }
除了类Mono的作用和特性外,我理解这段代码。我做了很多搜索,但没有直接指出重点:**类Mono是什么**以及**何时使用它**?
英文:
I have this following code:
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
@Component
public class GreetingHandler 
    public Mono<ServerResponse> hello(ServerRequest request) {
        return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
        .body(BodyInserters.fromValue("Hello Spring!"));
    }
}
I understand this code except what the class Mono does and what are its features. I did a lot of search but it didn't goes straight to the point: what is the class Mono and when to use it?
答案1
得分: 58
一个Mono<T>是一种特殊的Publisher<T>,它最多发出一个项,然后(可选地)以onComplete信号或onError信号终止。
它仅提供了Flux可用操作符的子集,一些操作符(尤其是将Mono与另一个Publisher组合的操作符)会切换到Flux。例如,Mono#concatWith(Publisher)返回一个Flux,而Mono#then(Mono)返回另一个Mono。
请注意,您可以使用Mono表示仅具有完成概念(类似于Runnable)的无值异步过程。要创建一个,您可以使用一个空的Mono<Void>。
Mono和Flux都是反应流。它们在表达上有所不同。Mono是一个0到1个元素的流,而Flux是一个0到N个元素的流。
这两个流的语义差异非常有用,例如,向Http服务器发出请求预期接收0或1个响应,在这种情况下使用Flux是不合适的。相反地,对一个区间上的数学函数进行计算期望每个区间中的数字产生一个结果。在这种情况下,使用Flux是适当的。
如何使用它:
Mono.just("Hello World !").subscribe(
  successValue -> System.out.println(successValue),
  error -> System.err.println(error.getMessage()),
  () -> System.out.println("Mono consumed.")
);
// 这将在控制台显示:
// Hello World !
// Mono consumed.
// 在出现错误的情况下,它将显示:
// **错误消息**
// Mono consumed.
Flux.range(1, 5).subscribe(
  successValue -> System.out.println(successValue),
  error -> System.err.println(error.getMessage()),
  () -> System.out.println("Flux consumed.")
);
// 这将在控制台显示:
// 1
// 2
// 3
// 4
// 5
// Flux consumed.
// 现在想象一下,当在Flux中操作值时,值4会引发异常。
// 控制台上的结果将是:
// 发生了错误
// 1
// 2
// 3
//
// 注意,"Flux consumed."不会显示,因为Flux还没有被完全消耗。这是因为如果发生错误,流会停止处理未来的值。而且,错误会在成功的值之前处理。
来源:Reactor Java #1 - How to create Mono and Flux?,Mono, an Asynchronous 0-1 Result
可能会有帮助:Mono文档
英文:
A Mono<T> is a specialized Publisher<T> that emits at most one item and then (optionally) terminates with an onComplete signal or an onError signal.
It offers only a subset of the operators that are available for a Flux, and some operators (notably those that combine the Mono with another Publisher) switch to a Flux. For example, Mono#concatWith(Publisher) returns a Flux while Mono#then(Mono) returns another Mono.
Note that you can use a Mono to represent no-value asynchronous processes that only have the concept of completion (similar to a Runnable). To create one, you can use an empty Mono<Void>.
Mono and Flux are both reactive streams. They differ in what they express. A Mono is a stream of 0 to 1 element, whereas a Flux is a stream of 0 to N elements.
This difference in the semantics of these two streams is very useful, as for example making a request to an Http server expects to receive 0 or 1 response, it would be inappropriate to use a Flux in this case. On the opposite, computing the result of a mathematical function on an interval expects one result per number in the interval. In this other case, using a Flux is appropriate.
How to use it:
Mono.just("Hello World !").subscribe(
  successValue -> System.out.println(successValue),
  error -> System.err.println(error.getMessage()),
  () -> System.out.println("Mono consumed.")
);
// This will display in the console :
// Hello World !
// Mono consumed.
// In case of error, it would have displayed : 
// **the error message**
// Mono consumed.
Flux.range(1, 5).subscribe(
  successValue -> System.out.println(successValue),
  error -> System.err.println(error.getMessage()),
  () -> System.out.println("Flux consumed.")
);
// This will display in the console :
// 1
// 2
// 3
// 4
// 5
// Flux consumed.
// Now imagine that when manipulating the values in the Flux, an exception
// is thrown for the value 4. 
// The result in the console would be :
// An error as occurred
// 1
// 2
// 3
//
// As you can notice, the "Flux consumed." doesn't display because the Flux
// hasn't been fully consumed. This is because the stream stop handling future values
// if an error occurs. Also, the error is handled before the successful values.
sources: Reactor Java #1 - How to create Mono and Flux?, Mono, an Asynchronous 0-1 Result
it might be helpful: Mono doc
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论