Spring Reactor:Optional <t>对应的类是什么?

时间:2019-04-28 08:47:04

标签: java spring reactive-programming project-reactor reactor

所以我有一个Flux<Foo>,我想将每个Foo映射到Baz。问题是,getBaz(Foo foo)可能会抛出IOException

所以我考虑使用Mono<Baz> getBazRx(Foo foo)方法,该方法在发生异常的情况下将返回Mono.just(baz)Mono.empty()

然后将以Flux<Mono<Baz>>结尾,从而提醒Optional<T>容器。

在Spring Reactor中是这样吗?如何正确食用?

2 个答案:

答案 0 :(得分:2)

在反应流中,通常通过从流中删除不存在的元素(例如,空Mono或元素被删除的Flux)来处理“可选”,而不是使用{{ 1}},Flux<Optional>Mono<Optional>

调用同步Flux<Mono>方法时,可以使用单个getBaz操作,如下所示:

.handle

调用异步flux .handle((foo, sink) -> { try { // propagate Baz down the stream sink.next(getBaz(foo)); } catch (IOException e) { // Since sink.next is not called here, // the problematic element will be dropped from the stream log.error(e); } }) 方法(返回getBazRx)时,可以在Mono / onErrorResume / flatMap内使用flatMapSequential,像这样:

concatMap

(或者您可以将flux .flatMap(foo -> getBazRx(foo) .onErrorResume(t -> { log.error(t); return Mono.empty(); })) 移到.onErrorResume内,具体取决于您要捕获并忽略异常的位置)

此外,由于您在问题中提到了它...如果要创建将.getBazRx包裹起来的getBazRx,则如果{ {1}}可能会阻止:

getBaz

该实现实际上只是一个同步方法模拟一个异步方法。它有两个问题:

  1. 工作立即完成,而不是在订阅返回的getBaz
  2. 之后
  3. 如果Mono<Baz> getBazRx(Foo foo) { // BAD!!! try { return Mono.just(getBaz(foo)); } catch (IOException e) { return Mono.error(e) // or Mono.empty() if you want to ignore } } 被阻止,您最终可能会阻止事件循环

相反,您应该将工作推迟到订阅了单声道后,然后在用于阻止操作的Mono上运行任何阻止操作,如下所示:

getBaz

答案 1 :(得分:0)

由于要跳过错误(例如仅记录错误),因此可以使用onErrorContinue。另外,由于getBaz引发了一个已检查的异常,因此我们需要捕获它,并return(而不是抛出)一个RuntimeException。 Reactor有一个实用程序方法可以执行此Exceptions.propagate

flux
  .map(foo -> {
      try {
        return getBaz(foo);
      } catch (IOException e) {
        return Exceptions.propagate(e);
      }
  })
  .onErrorContinue(RuntimeException.class, (t, b) -> log.error(t))
  .subscribe(baz -> log.info("Read value {}", baz));