#kotlin #reactive-programming #project-reactor
#kotlin #реактивное программирование #проект-реактор
Вопрос:
Когда я связываю несколько zipWhen
вызовов, результатом будет a Tuble2<Tuple2<Foo, Bar>, Bam>
вместо a Tuple3<Foo, Bar, Bam>
. Это становится хуже с каждым последующим zipWhen
.
Пример:
val getFoo()
.zipWhen { foo ->
getBar(foo)
}
.zipWhen { fooBar ->
getBam(fooBar.t1, fooBar.t2)
}
.doOnNext { fooBarBam ->
log.debug { "foo: ${fooBarBam.t1.t1}" }
log.debug { "bar: ${fooBarBam.t1.t2}" }
log.debug { "bam: ${fooBarBam.t2}" }
}
Какой самый элегантный и многоразовый способ получить Tubple3
в doOnNext?
Ответ №1:
Что вы можете сделать, так это использовать zipWhen с комбинатором типа:
getFoo()
.zipWhen {foo -> getBar(foo) }
.zipWhen({ t -> getBam(t.t1, t.t2) }, {a, b -> Tuples.of(a.t1, a.t2, b)})
.doOnNext { fooBarBam ->
log.debug { "foo: ${fooBarBam.t1}" }
log.debug { "bar: ${fooBarBam.t2}" }
log.debug { "bam: ${fooBarBam.t3}" }
}
Ответ №2:
Полезные утилиты:
fun <T1, T2, T3, T4, T5, U> flat(t: Tuple5<T1, T2, T3, T4, T5>, u: U): Tuple6<T1, T2, T3, T4, T5, U> = Tuples.of(t.t1, t.t2, t.t3, t.t4, t.t5, u)
fun <U, T1, T2, T3, T4, T5> flat(u: U, t: Tuple5<T1, T2, T3, T4, T5>): Tuple6<U, T1, T2, T3, T4, T5> = Tuples.of(u, t.t1, t.t2, t.t3, t.t4, t.t5)
fun <T1, T2, T3, T4, U> flat(t: Tuple4<T1, T2, T3, T4>, u: U): Tuple5<T1, T2, T3, T4, U> = Tuples.of(t.t1, t.t2, t.t3, t.t4, u)
fun <U, T1, T2, T3, T4> flat(u: U, t: Tuple4<T1, T2, T3, T4>): Tuple5<U, T1, T2, T3, T4> = Tuples.of(u, t.t1, t.t2, t.t3, t.t4)
fun <T1, T2, T3, U> flat(t: Tuple3<T1, T2, T3>, u: U): Tuple4<T1, T2, T3, U> = Tuples.of(t.t1, t.t2, t.t3, u)
fun <U, T1, T2, T3> flat(u: U, t: Tuple3<T1, T2, T3>): Tuple4<U, T1, T2, T3> = Tuples.of(u, t.t1, t.t2, t.t3)
fun <T1, T2, U> flat(t: Tuple2<T1, T2>, u: U): Tuple3<T1, T2, U> = Tuples.of(t.t1, t.t2, u)
fun <U, T1, T2> flat(u: U, t: Tuple2<T1, T2>): Tuple3<U, T1, T2> = Tuples.of(u, t.t1, t.t2)
Использование:
import reactor.kotlin.core.util.function.*
fun doStuff(id:Long){
getProduct(id)
.zipWith(Mono.just("a string"))
.zipWith(Mono.just(42),
{ t, u -> flat(t, u) })
.zipWith(Mono.just("anotherstring"),
{ t, u -> flat(t, u) })
.doOnNext { (product, aString, number, anotherString) ->
log.debug(product.description " " aString " " number " " anotherString)
}
}
Импорт заключается в деструктурировании полученного кортежа.
Ответ №3:
Самый очевидный способ, которым я хочу выставить себя на голосование:
.map {
Tuples.of(it.t1.t1, it.t1.t2, it.t2)
}
и извлечение функции.
fun <T1, T2, T3> flatTuple(t: Tuple2<Tuple2<T1, T2>, T3>): Tuple3<T1, T2, T3> =
Tuples.of(t.t1.t1, t.t1.t2, t.t2)
// ...
.map { flatTuple(it) }