gpt4 book ai didi

kotlin - 取消信号上的Kotlin流收集

转载 作者:行者123 更新时间:2023-12-02 11:57:51 24 4
gpt4 key购买 nike

我正在努力为Flow创建一个'takeUntilSignal'运算符-一种扩展方法,当另一个流程生成输出时,该方法将取消该流程。

fun <T> Flow<T>.takeUntilSignal(signal: Flow<Unit>): Flow<T>

我的最初工作是尝试在与主要流程集合相同的协程范围内启动信号流的收集,并取消协程范围:
fun <T> Flow<T>.takeUntilSignal(signal: Flow<Unit>): Flow<T> = flow {
kotlinx.coroutines.withContext(coroutineContext) {
launch {
signal.take(1).collect()
println("signalled")
cancel()
}
collect {
emit(it)
}
}
}

但这是行不通的(并且使用Flow明确禁止使用的“withContext”方法以防止使用)。

编辑
我将以下可憎性混为一谈,这很不符合定义(结果流只会在从主流中首次排放后才取消),我觉得那里还有更好的方法:
fun <T> Flow<T>.takeUntilSignal(signal: Flow<Unit>): Flow<T> =
combine(
signal.map { it as Any? }.onStart { emit(null) }
) { x, y -> x to y }
.takeWhile { it.second == null }
.map { it.first }

编辑2
另一种尝试,使用channelFlow:
fun <T> Flow<T>.takeUntilSignal(signal: Flow<Unit>): Flow<T> =
channelFlow {
launch {
signal.take(1).collect()
println("hello!")
close()
}
collect { send(it) }
close()
}

最佳答案

使用couroutineScope并在其中启动新的协程:

fun <T> Flow<T>.takeUntilSignal(signal: Flow<Unit>): Flow<T> = flow {
try {
coroutineScope {
launch {
signal.take(1).collect()
println("signalled")
this@coroutineScope.cancel()
}

collect {
emit(it)
}
}

} catch (e: CancellationException) {
//ignore
}
}

关于kotlin - 取消信号上的Kotlin流收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59102397/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com