HI folks, I have a Channel and I want to filter so...
# coroutines
s
HI folks, I have a Channel and I want to filter some value when receive it and await the first time. I try to use
receiveAsFlow().filter {}.collect()
but I think that this is not the right aproach be cause do not work. How I can await the first appearance of a value in a Channel?
j
I’m not sure what you’re trying to do here. Do you need other consumers on this channel? or are you done once you have consumed it in this one place? If you’re just interested in getting the first value matching your predicate, and then you want to cancel the channel because it’s not useful to anyone else, I would go with:
Copy code
channel.consumeAsFlow().first { ... }
If other consumers need to use your channel as well, and want to see all values (including the one that this statement would return), then you’ll need to use a broadcast channel instead (to send the same value to multiple consumers). Once you have a broadcast channel, you can do:
Copy code
broadcastChannel.asFlow().first { ... }
Using
receiveAsFlow()
is kind of tricky because it will fan out the values between all consumers (a given value would only reach one consumer), so you can’t be sure that the one who needs this first value matching the predicate will get it.
🎉 1
s
Tkx, you help a lot.
broadcastChannel.asFlow().first {}
is the one.
j
Glad to help! 🙂 By the way, note that you can create one flow with
asFlow()
and share it between all your consumers. Each collection or other terminal operators (like
first()
) on this flow creates a new subscription to your broadcast channel, and cancels it in the end.
s
If I use
BroadcastChannel.openSubscription
I could use
consumeAsFlow
without any problem too?
j
Yes, it should be equivalent, because
consumeAsFlow()
basically auto-cancels the channel (in this case the subscription channel) after the first consumption of the flow.