louiscad
08/20/2018, 8:22 AMchannelA: Channel<A>
and channelB: Channel<B>
, I want to call a method like update(a: A, b: B)
each time I get a value from any channel, that is, if I receive from channelA
, I want it to be called with the new A
value, and the same B
value as previously received.
Each time I have a use case for it, I feel like I'm writing disposable/throwaway code that is a bit error-prone and quite boilerplate-y. If you have any clue about a solution to do it right once for all, in a kind of generic way, please tell!
Bonus points if your solution can also work with other callbacks and not just Channel
gildor
08/20/2018, 8:22 AMmerge
operator would help? Just merge multiple channels to onelouiscad
08/20/2018, 8:24 AMChannel
(I've searched through autocompletion, and I only found zip
which does not do what I want as it needs a new value from each channel)julioyg
08/20/2018, 8:25 AMlouiscad
08/20/2018, 8:27 AMPair
, Triple
or other grouping objects, if this is possiblegildor
08/20/2018, 8:29 AMfun <T> merge(vararg channels: ReceiveChannel<T>) = produce {
for (c in channels) {
launch(coroutineContext) {
for (v in c) {
send(v)
}
}
}
}
(just a draft, not tested, probably can be rewritten with select instead)louiscad
08/20/2018, 8:31 AMfun <T> merge(vararg channels: ReceiveChannel<T>) = produce {
try {
channels.map { channel ->
launch(coroutineContext) {
for (e in channel) send(e)
}
}.joinAll()
} finally {
channels.forEach { it.cancel() }
}
}
gildor
08/20/2018, 8:39 AMyou lose type informations if you merge channels of different typesYou can use wrapper over your data or just Any
is not conflatedYou can use conflated channel under the hood, but it cannot be just an operator anymore, but probably class implementation detail
louiscad
08/20/2018, 8:42 AMconsumesAll
seems less efficient that a simple forEach
in this casewithoutclass
08/20/2018, 9:23 AMlouiscad
08/20/2018, 2:50 PMbj0
08/20/2018, 5:26 PMlouiscad
08/20/2018, 6:54 PMbj0
08/20/2018, 7:04 PMselect
on channels -> update
on returned itemlouiscad
08/21/2018, 12:03 AMconflateAll
is called (on each update from any callback/channel)bj0
08/21/2018, 12:05 AMselect
would take care of the 'get a value from any channel' partDaniel Tam
08/21/2018, 6:48 AMlouiscad
08/21/2018, 7:28 AMcombineLatest
seems to work for only 2 `Observable`s, while my ConflatedValues
class works for any number of properties/callbacks/channels