从Mono列表中获取第一个onNext信号

时间:2019-03-03 03:14:56

标签: kotlin spring-webflux project-reactor

请考虑有3个函数可生成Mono<Int> s。我正在尝试获取任何Monos发出的第一个结果。这是一个描述我在寻找什么的测试:

fun main() {
  StepVerifier
    .create(firstElement())
    .expectSubscription()
    .expectNext(3)
    .expectComplete()
    .verify()
}

fun firstElement(): Mono<Int> = Flux.concat(_1(), _2(), _3(), _4()).next()

fun _1(): Mono<Int> = 1.toMono().delayElement(Duration.ofMillis(1000))
fun _2(): Mono<Int> = Mono.empty()
fun _3(): Mono<Int> = 3.toMono().delayElement(Duration.ofMillis(500))
fun _4(): Mono<Int> = Mono.error(RuntimeException())

问题出在firstElement()中,如何产生3,因为它是第一个发出元素的对象。但是,您可以从任何Monos中看到:

  • 它们中的任何一个都有可能比其余的发射更快
  • 它们中的任何一个都可能发出空或onComplete()
  • 它们中的任何一个都可能发出错误或onError()

我尝试了几种运算符:

  • Mono.zip {...}要求它们全部发出,因为返回值为Tuple<Int!>
  • Mono.first(...)Flux.first(...).next()发送onComplete()和/或onError()
  • Flux.concat(...)消除了onComplete()onError(),但仍根据给定Publisher<T> s的顺序顺序订阅

1 个答案:

答案 0 :(得分:2)

您可以在错误的情况下使用空Mono恢复并合并功能

private Mono<Integer> firstElement() {
    return Flux.merge(
            _1().onErrorResume(ignored -> Mono.empty()),
            _2().onErrorResume(ignored -> Mono.empty()),
            _3().onErrorResume(ignored -> Mono.empty()),
            _4().onErrorResume(ignored -> Mono.empty()))
            .next();
}