假设我有这样的东西:
Mono.just(a)
.flatMap(...) // init
// set fields on a if error occurs
.flatMap(...) // finalize
.subscribe();
在最后一个flatMap
中,我将根据a
中字段的值执行一些最终逻辑。特别是我需要知道init期间是否发生了错误...
所以我需要一种可以拦截错误并允许操作原始对象的方法。
如果我没记错的话,所有onError*
方法都将返回原始对象,而不允许对其进行更新。
doOnError
似乎也无法解决我的问题。
有没有办法实现我所需要的?
答案 0 :(得分:2)
请记住,这是一连串的离散和(可能)异步步骤。进入步骤后,您获得的唯一上下文是上一步的输出,形式为onNext
,onComplete
和onError
信号,以及可以公开的所有Java核心语言功能给你。例如,如果您要在Flux
lambda中组装内部flatmap
,则Java使您可以访问该lambda的输入参数。
稍后可能是您所需的解决方案:一个可以获取原始值的范围。
这样,第一个flatMap
可以作为封闭范围并处理名义和错误情况。像这样:
Mono<B> processed = Mono.just(a)
.flatMap(a -> init(a)
.onErrorResume(fallback(a))
)
.flatMap(...); // finalize
processed.subscribe();
//for illustration purposes, what process and fallback may typically look like:
Mono<B> init(A a) {
return Mono.zip(
asyncServiceStuff.process(a.stuff),
asyncServiceOtherStuff.process(a.otherStuff),
(bPart1, bPart2) -> new B(bPart1, bPart2)
);
}
Mono<B> fallback(A original) {
return Mono.just(new FallbackB(a.otherStuff));
}
也就是说,您似乎想从a
创建后备广告,该后备广告已经可以在方法的 scope 中使用(理想情况下作为final
输入参数或变量)。
答案 1 :(得分:0)
您丢失了以下事实:每个下一个反应式运算符都会为我们构建一个新的Mono
实例。因此,如果再添加一个运算符,这对您来说并不重要:
/**
* Simply emit a captured fallback value when any error is observed on this {@link Mono}.
*
* <p>
* <img class="marble" src="doc-files/marbles/onErrorReturnForMono.svg" alt="">
*
* @param fallback the value to emit if an error occurs
*
* @return a new falling back {@link Mono}
*/
public final Mono<T> onErrorReturn(final T fallback) {
Mono.just(a)
.flatMap(...)
.onErrorReturn(fallbackValue)
.flatMap(...)
.subscribe();
您绝对可以对所有其他onError*
进行调查,以查找可能的错误处理变体。
答案 2 :(得分:0)
Mono.just(a)
.flatMap(...) // init
// set fields on a if error occurs
.onErrorResume(getFallbackMono(a))
.flatMap(...) // finalize
.subscribe();
...
private Mono<ClassOfA> getFallbackMono(ClassOfA a) {
return Mono.just(getMutatedA(a));
}
.onErrorResume
将使流返回到后备状态。在这里,您可以创建一个具有a
突变值的新流。
.doOnError()
是一个副作用运算符。我会用它来记录错误。