doc: 阅读spring reactor文档
This commit is contained in:
@@ -47,6 +47,10 @@
|
|||||||
- [publishOn](#publishon)
|
- [publishOn](#publishon)
|
||||||
- [subscribeOn](#subscribeon)
|
- [subscribeOn](#subscribeon)
|
||||||
- [`subscribeOn`原理](#subscribeon原理)
|
- [`subscribeOn`原理](#subscribeon原理)
|
||||||
|
- [Handling Errors](#handling-errors)
|
||||||
|
- [static fallback value](#static-fallback-value)
|
||||||
|
- [catch and swallow error](#catch-and-swallow-error)
|
||||||
|
- [fallback method](#fallback-method)
|
||||||
|
|
||||||
# Reactor
|
# Reactor
|
||||||
## Reactive Programming
|
## Reactive Programming
|
||||||
@@ -642,8 +646,117 @@ final Flux<String> flux = Flux
|
|||||||
|
|
||||||
new Thread(() -> flux.subscribe(System.out::println));
|
new Thread(() -> flux.subscribe(System.out::println));
|
||||||
```
|
```
|
||||||
|
### Handling Errors
|
||||||
|
在reactive stream中,errors是终止事件,一旦error被触发,sequence的生成将会被停止,并且将会沿着reactor chain的下游一直传递道`subscriber#onError`。
|
||||||
|
|
||||||
|
error应该在应用程序的级别被处理,处理方案如下:
|
||||||
|
- 在ui上展示错误信息
|
||||||
|
- 向rest endpoint发送error payload
|
||||||
|
|
||||||
|
故而,`subscriber#onError`方法应该被定义。
|
||||||
|
|
||||||
|
reactor同样支持在chain的中间通过`error-handling`来处理error,示例如下所示:
|
||||||
|
```java
|
||||||
|
Flux.just(1, 2, 0)
|
||||||
|
.map(i -> "100 / " + i + " = " + (100 / i)) //this triggers an error with 0
|
||||||
|
.onErrorReturn("Divided by zero :("); // error handling example
|
||||||
|
```
|
||||||
|
|
||||||
|
> 在reactor中,任何error都代表终止事件,`即使使用了error-handling operator,original sequence在出现error后也不会继续。
|
||||||
|
>
|
||||||
|
> 故而,error-handling将`onError`信号转化为了一个新sequence的开始(fallback one),即通过新sequence替换了上游旧的`terminated sequence`。
|
||||||
|
|
||||||
|
> 在`FluxOnErrorReturn.ReturnSubscriber#onError`的实现中,operator将`Throwable`转换为了`onNext(fallbackValue)`和`onComplete`两个调用,即在向下游发送`onNext(fallbackValue)`信号之后,也会终止序列。
|
||||||
|
|
||||||
|
通常来说,常见的异常才处理方式如下:
|
||||||
|
|
||||||
|
#### static fallback value
|
||||||
|
该场景类似于
|
||||||
|
```java
|
||||||
|
try {
|
||||||
|
return doSomethingDangerous(10);
|
||||||
|
}
|
||||||
|
catch (Throwable error) {
|
||||||
|
return "RECOVERED";
|
||||||
|
}
|
||||||
|
```
|
||||||
|
可以调用`onErrorReturn`方法,示例如下:
|
||||||
|
```java
|
||||||
|
Flux.just(10)
|
||||||
|
.map(this::doSomethingDangerous)
|
||||||
|
.onErrorReturn("RECOVERED");
|
||||||
|
```
|
||||||
|
`onErrorReturn`还存在一个接受`Predicate`的重载方法,可以决定是否对异常执行recover操作,示例如下:
|
||||||
|
```java
|
||||||
|
Flux.just(10)
|
||||||
|
.map(this::doSomethingDangerous)
|
||||||
|
.onErrorReturn(e -> e.getMessage().equals("boom10"), "recovered10");
|
||||||
|
```
|
||||||
|
|
||||||
|
#### catch and swallow error
|
||||||
|
如果不想将异常替换为fallback value,而是忽视产生的error,仅向下游传递正常生成的元素,可以使用`onErrorComplete`方法(例如, `1,2,3...`序列在向下进行传递时,如果`2`的下游operator执行发生异常,那么`onErrorComplete`会忽略`2`产生的error,仅向下游传递`1`)。
|
||||||
|
|
||||||
|
`onErrorComplete`的使用示例如下:
|
||||||
|
```java
|
||||||
|
Flux.just(10,20,30)
|
||||||
|
.map(this::doSomethingDangerousOn30)
|
||||||
|
.onErrorComplete();
|
||||||
|
```
|
||||||
|
> onErrorComplete会将onError信号转化为onComplete信号。
|
||||||
|
|
||||||
|
类似于`onErrorReturn`,`onErrorComplete`同样存在一个重载方法接受`Predicate`,可以通过该断言判断是否对error执行`recover`操作。
|
||||||
|
- 若执行recover操作,则会调用`subscriber#onComplete`
|
||||||
|
- 若不执行recover操作,则会调用`subscriber#onError`
|
||||||
|
|
||||||
|
#### fallback method
|
||||||
|
如果在处理数据时,存在多种方法,例如`m1,m2`,并且在尝试`m1`失败时想要再尝试`m2`,可以使用`onErrorResume`方法。
|
||||||
|
|
||||||
|
其等价于如下逻辑:
|
||||||
|
```java
|
||||||
|
String v1;
|
||||||
|
try {
|
||||||
|
v1 = callExternalService("key1");
|
||||||
|
}
|
||||||
|
catch (Throwable error) {
|
||||||
|
v1 = getFromCache("key1");
|
||||||
|
}
|
||||||
|
|
||||||
|
String v2;
|
||||||
|
try {
|
||||||
|
v2 = callExternalService("key2");
|
||||||
|
}
|
||||||
|
catch (Throwable error) {
|
||||||
|
v2 = getFromCache("key2");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
和上述逻辑等价的是如下代码:
|
||||||
|
```java
|
||||||
|
Flux.just("key1", "key2")
|
||||||
|
.flatMap(k -> callExternalService(k)
|
||||||
|
.onErrorResume(e -> getFromCache(k))
|
||||||
|
);
|
||||||
|
```
|
||||||
|
其中,`onErrorResume`返回的都是一个`Publisher`
|
||||||
|
|
||||||
|
`onErrorResume`的底层逻辑实现如下:
|
||||||
|
- 其会根据`onErrorResume`中传入的`Function<? super Throwable, ? extends Publisher<? extends T>>`参数和`error`来构建一个新的publisher
|
||||||
|
- 然后,对新的publisher执行`subscribe`操作,并向下游返回新publisher的sequence
|
||||||
|
|
||||||
|
`onErrorResume`同样拥有一个重载函数接受`Predicate`,决定是否执行recover逻辑。除此之外,其接受`Function<? super Throwable, ? extends Publisher<? extends T>>`类型参数,可以根据抛出的异常来决定fallback sequence,示例如下:
|
||||||
|
```java
|
||||||
|
Flux.just("timeout1", "unknown", "key2")
|
||||||
|
.flatMap(k -> callExternalService(k)
|
||||||
|
.onErrorResume(error -> {
|
||||||
|
if (error instanceof TimeoutException)
|
||||||
|
return getFromCache(k);
|
||||||
|
else if (error instanceof UnknownKeyException)
|
||||||
|
return registerNewEntry(k, "DEFAULT");
|
||||||
|
else
|
||||||
|
return Flux.error(error);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
```
|
||||||
|
> 在上述示例中,`Flux.error`会重新抛出上述异常
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user