question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

combine(flow1, flow2) does not work instantly

See original GitHub issue

Hi. I am writing a mini-framework with reactive properties. One of the core concepts in this framework is a computed property. This property recalculates its value automatically whenever values of some other properties are changed.

For example:

    var appleCount by state(0)
    var bananaCount by state(0)
    val fruitCount by computed(::appleCount, ::bananaCount) { a, b -> a + b }

    fun changeFruits() {
        appleCount = 2
        bananaCount = 3
        // fruitCount is 5 here
    }

My framework uses MutableStateFlow and combine under the hood. The problem is that it is not always works as expected. The computed value is not updated instantly in some cases. For example:

    fun changeFruits() {
        appleCount = 2
        bananaCount = 3
        appleCount = 20
        bananaCount = 30
        // fruitCount is 5 here, but 50 is expected
    }

I wrote a test to reproduce the problem:

    @Test
    fun `flows are combined instantly`() = runBlockingTest {
        val flow1 = MutableStateFlow(0)
        val flow2 = MutableStateFlow(0)
        val resultFlow = MutableStateFlow(0)

        val job = launch {
            combine(flow1, flow2) { v1, v2 ->
                v1 + v2
            }.collect {
                resultFlow.value = it
            }
        }

        flow1.value = 2
        flow2.value = 3
        flow1.value = 20
        flow2.value = 30

        assertEquals(50, resultFlow.value)
        job.cancel()
    }

In the real code I use Main.immediate dispatcher. That’s why I expect an instant recalculation.

Take a look, please. If it is an expected behavior, how can I solve my problem?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
elizarovcommented, Oct 6, 2020

There is no such guarantee. In simple cases it will, indeed, work seemingly synchronously. In complex nested cases, when you mutate a value inside another mutation (which has been already immedaitely-dispatched) it will not work this way.

0reactions
aartikovcommented, Oct 7, 2020

Thanks 👍

Read more comments on GitHub >

github_iconTop Results From Across the Web

Android: Application gets stuck in flow combine and does not ...
I'd suspect that one of your flows is actually empty. Could you ensure that both of them are emitting values?
Read more >
Combining flows: merge, zip, and combine - Kt. Academy
Let's talk about combining two flows into one. There are a few ways to do this. The simplest involves merging the elements from...
Read more >
How to combine two flows into one in below usecase
Solved: Hi, I have a simple flow setup that checks if todays date is 120 days from expiration date, along with that also...
Read more >
Combining Kotlin Flows with Select Expressions
The combine operator returns a Flow whose values are generated with transform function by combining the most recently emitted values by each flow....
Read more >
How to Combine Kotlin Flows - Better Programming
Unlike zip , flattenMerge won't stop execution when one of the Flow s is completed. Take a look at the output: Output 1...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found