栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

用Reactor抛出异常的正确方法

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

用Reactor抛出异常的正确方法

有几种方法可以被视为方便的异常抛出方法:

使用处理元素
Flux/Mono.handle

可以简化可能导致错误或空流的元素处理的一种方法是operator

handle

以下代码显示了如何使用它来解决问题:

Mono.just(userId)    .map(repo::findById)    .handle((user, sink) -> {        if(!isValid(user)){ sink.error(new InvalidUserException());        } else if (isSendable(user)) sink.next(user);        }        else { //just ignore element        }    })

如我们所见,

.handle
操作员需要通过
BiConsumer<T,SynchronousSink<>
才能处理元素。在这里,我们的BiConsumer中有两个参数。第一个元素是上游元素,第二个元素是上游元素,
SynchronousSink
它帮助我们向下游同步提供元素。这样的技术扩展了提供元素处理的不同结果的能力。例如,如果元素无效,我们可以向该元素提供错误,
SycnchronousSync
这将取消上游
onError
并向下游产生信号。反过来,我们可以使用相同的
handle
运算符来“过滤”
。一旦手柄
BiConsumer
被执行并且没有提供任何元素,Reactor会将其视为一种过滤,并将为我们请求其他元素。最后,在元素有效的情况下,我们可以简单地在
SynchronousSink#next
下游调用和传播我们的元素,或者在其上应用一些映射,因此这里将
handle
作为
map
操作符。此外,我们可以安全地使用该运算符,而不会影响性能,并提供复杂的元素验证,例如元素验证或向下游发送错误。

使用
#concatMap
+ 抛出
Mono.error

在映射期间引发异常的选项之一是替换

map
concatMap
。从本质上讲,
concatMap
它的作用几乎相同
flatMap
。唯一的区别是
concatMap
一次仅允许一个子流。这种行为大大简化了内部实现,并且不影响性能。因此,我们可以使用以下代码来以更实用的方式引发异常:

Mono.just(userId)    .map(repo::findById)    .concatMap(user-> {        if(!isValid(user)){ return Mono.error(new InvalidUserException());        }        return Mono.just(user);    })

在上述示例中,如果用户无效,我们将使用返回异常

Mono.error
。我们可以使用
Flux.error
以下方法对通量执行相同的操作:

Flux.just(userId1, userId2, userId3)    .map(repo::findById)    .concatMap(user-> {        if(!isValid(user)){ return Flux.error(new InvalidUserException());        }        return Mono.just(user);    })

注意 ,在两种情况下,我们都返回仅包含一个元素的 冷流 。在Reactor中,在返回的流是冷 标量
流的情况下,有一些优化可以提高性能。因此,建议使用流量/单声道

concatMap
+
.just
empty
error
其结果是,当我们需要更复杂的映射,这可能与最终
return null
throw new ...


注意! 永远不要检查传入元素的可空性。Reactor项目永远不会

null
为您发送值,因为这违反了Reactive
Streams规范(请参见规则2.13)。
因此,如果
repo.findById
返回null,Reactor将为您抛出NullPointerException。

等等,为什么
concatMap
比这更好
flatMap

从本质上讲,

flatMap
它旨在合并一次执行的多个子流中的元素。这意味着flatMap在其下应具有异步流,因此它们可能在多个线程上处理数据,也可能是多个网络调用。随后,这种期望对实现产生了很大的影响,因此
flatMap
应该能够处理来自多个流的数据
Thread
(意味着并发数据结构的使用),如果另一个流耗尽了,则使元素排队(意味着
Queue
为每个s
分配额外的内存子流),并且不违反反应式流规范规则(意味着确实非常复杂的实现)。计算所有这些事实以及我们取代平原的事实
map
使用
Flux/Mono.error
(不改变执行的同步性)引发异常的更方便的方式(同步操作)导致我们不需要这样一个复杂的运算符,并且可以使用更简单
concatMap
的异步处理对象一次只能处理一个流,并进行了一些优化以处理标量冷流。

使用抛出异常
switchOnEmpty

因此,在结果为空时引发异常的另一种方法是

switchOnEmpty
operator。以下代码演示了如何使用该方法:

Mono.just(userId)    .flatMap(repo::findById)    .switchIfEmpty(Mono.error(new UserNotFoundExeception()))

如我们所见,在这种情况下,

repo::findById
应该将
Mono
of
User
作为返回类型。因此,在
User
找不到实例的情况下,结果流将为空。因此,Reactor将调用
Mono
指定为
switchIfEmpty
parameter
的Alternative 。

照原样抛出您的异常

可以将其视为可读性差的代码或不良做法( 我个人认为 ),但是您可以像使用Project
Reactor一样引发异常。即使这样做在某种程度上可能会违反Reactive Streams规范( 在这种情况下 从语义的角度来看是 违反
的,因为在幕后的运算符是s

Subscriber
链中
Subscriber
的a,因此-
从语义上讲,在lambda中引发异常可以映射为引发
onNext
违反规范规则2.13的方法中的异常)。但是,由于Reactor会为您捕获引发的异常,然后将其作为
onError
信号传播到下游,因此不禁止这样做。

外卖

  1. 使用
    .handle
    运算符以提供复杂的元素处理
  2. 当我们需要在映射过程中引发异常时,请使用
    concatMap
    +
    Mono.error
    ,但是这种技术最适合异步元素处理的情况。
  3. 当我们已经到位时使用
    flatMap
    +
    Mono.error``flatMap
  4. Null
    因为返回类型是禁止的,所以您将
    null
    在下游而不是下游使用
    map``onError``NullPointerException
  5. 使用
    switchIfEmpty
    在所有情况下,当你需要发送一个错误信号,如果在调用一些特定的函数的结果与完成


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/453113.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号