-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add withLatestFrom operator. #1315
base: develop
Are you sure you want to change the base?
Add withLatestFrom operator. #1315
Conversation
0c66a10
to
80a0d5e
Compare
80a0d5e
to
4fa6c5a
Compare
Co-authored-by: Ray Ryan <[email protected]>
4fa6c5a
to
0575808
Compare
Gentle ping: Is the use case I've given adequate, or would more information be helpful? |
This will not be part of |
Do I correctly understand that this is My usecase is for example: loading places to map; user is moving with map, which cancels the previous fetching, also the loaded data depend on filter or other Flows. |
I don't think you can implement this with It's closer to a |
A simple implementation using only stable Flow APIs can be found here: https://pl.kotl.in/IYfZx_sKY |
I'm having trouble writing unit tests for the implementation in #1315 (comment) Here's what I've tried. @Test
fun `When receiver flow emits then resulting flow emits`() {
val firstFlowChannel = ConflatedBroadcastChannel<Char>()
val otherFlowChannel = ConflatedBroadcastChannel<Int>()
val resultingFlow =
firstFlowChannel.asFlow()
.withLatestFrom(otherFlowChannel.asFlow()) { a, b -> "$a$b"}
otherFlowChannel.offer(1)
firstFlowChannel.offer('a')
runBlocking {
val receiveChannel = resultingFlow.produceIn(this)
assertEquals("a1", receiveChannel.poll())
receiveChannel.cancel()
}
} This always fails with
I see |
@curioustechizen Don't |
@elizarov Thanks. That worked. If I change Do I understand correctly that |
@curioustechizen |
4a49830
to
aff8202
Compare
Is there anything blocking this PR? |
Use case: The processing of one flow (the operator's receiver) requires using the latest value emitted from another flow at the time of emission from the first flow. My specific use case involves combining a flow of events with a flow of event sinks (
(Event) -> Unit
). Whenever an event occurs (is emitted from the first flow), it should be sent to the most recent sink emitted from the second flow.The resulting flow is entirely driven by the first flow. This operator conflates and caches values from the second flow and passes them to a lambda to be combined with values from the first flow whenever the first flow emits. The resulting flow will start collecting both flows immediately, but will not call the transform function or emit anything until both flows emit at least one value. The resulting flow will remain active until either flow throws an exception, or the first flow completes. If the first flow completes before the second, the second flow is cancelled. If the second flow completes before the first, the latest value will continue to be cached and passed to the transform function every time the first flow emits.
This operator is similar to
combineLatest
, but it always emits immediately and only when the first flow emits (values from the first flow are not cached). The implementation in this PR reuses as much of the infrastructure as possible fromcombineLatest
. It collects the second flow using aCONFLATED
channel since the operator only cares about caching the most recently emitted value, so the second flow does not need to have any backpressure applied.This PR only includes a single overload of the operator, accepting a single other flow, since that is the only overload I have a concrete use case for.