diff --git a/CHANGELOG.md b/CHANGELOG.md index 81594548..a00c51a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## [Unreleased] - TBD + +### Fixed + +- `withLatestFrom`: fix the bug that the other Flow is not cancelled after the main Flow is completed. + ## [0.7.5] - Jan 28, 2024 ### Changed diff --git a/src/commonMain/kotlin/com/hoc081098/flowext/withLatestFrom.kt b/src/commonMain/kotlin/com/hoc081098/flowext/withLatestFrom.kt index 662863ba..c5c7c7f7 100644 --- a/src/commonMain/kotlin/com/hoc081098/flowext/withLatestFrom.kt +++ b/src/commonMain/kotlin/com/hoc081098/flowext/withLatestFrom.kt @@ -27,6 +27,7 @@ package com.hoc081098.flowext import com.hoc081098.flowext.internal.AtomicRef import com.hoc081098.flowext.internal.INTERNAL_NULL_VALUE import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow @@ -48,7 +49,7 @@ public fun Flow.withLatestFrom( try { coroutineScope { - launch(start = CoroutineStart.UNDISPATCHED) { + val otherCollectionJob = launch(start = CoroutineStart.UNDISPATCHED) { other.collect { otherRef.value = it ?: INTERNAL_NULL_VALUE } } @@ -60,6 +61,7 @@ public fun Flow.withLatestFrom( ), ) } + otherCollectionJob.cancelAndJoin() } } finally { otherRef.value = null @@ -69,4 +71,4 @@ public fun Flow.withLatestFrom( @Suppress("NOTHING_TO_INLINE") public inline fun Flow.withLatestFrom(other: Flow): Flow> = - withLatestFrom(other) { a, b -> a to b } + withLatestFrom(other, ::Pair) diff --git a/src/commonTest/kotlin/com/hoc081098/flowext/WithLatestFromTest.kt b/src/commonTest/kotlin/com/hoc081098/flowext/WithLatestFromTest.kt index 7f48dd9a..6ad4d53b 100644 --- a/src/commonTest/kotlin/com/hoc081098/flowext/WithLatestFromTest.kt +++ b/src/commonTest/kotlin/com/hoc081098/flowext/WithLatestFromTest.kt @@ -130,4 +130,16 @@ class WithLatestFromTest : BaseTest() { ), ) } + + @Test + fun cancelOtherFlowAfterSourceFlowCompleted() = runTest { + flowOf(1) + .withLatestFrom(neverFlow().startWith(2)) + .test( + listOf( + Event.Value(1 to 2), + Event.Complete, + ), + ) + } }