Tho*_*ook 5 kotlin kotlin-coroutines kotlin-flow
假设我有一个像这样的 API:
interface Foo {
val barFlow: Flow<Bar>
}
Run Code Online (Sandbox Code Playgroud)
我像这样消费它:
class FooConsumer(private val foo: Foo) {
init {
CoroutineScope(Dispatchers.IO).launch {
val bar = foo.barFlow.single()
println("Collected bar: $bar)
}
}
}
Run Code Online (Sandbox Code Playgroud)
根据文档,如果流为空,则可以抛出singlea 。NoSuchElementException然而,这让我很困惑,因为流上的终端操作将“等待”流的元素被发出。那么调用如何single知道流中没有元素呢?也许某个元素还没有被发射?
我的意思是,在幕后,调用single是在进行检查之前收集源流。因此,在执行 null 检查之前,必须至少发出 1 项,以便 null 检查永远不会成功,并且NoSuchElementException永远不会抛出 a (对于流属于不可为 null 类型的情况)。
那么NoSuchElementException只有可空类型的流才有可能吗?
这是源代码single:
/**
* The terminal operator, that awaits for one and only one value to be published.
* Throws [NoSuchElementException] for empty flow and [IllegalStateException] for flow
* that contains more than one element.
*/
public suspend fun <T> Flow<T>.single(): T {
var result: Any? = NULL
collect { value ->
if (result !== NULL) error("Expected only one element")
result = value
}
if (result === NULL) throw NoSuchElementException("Expected at least one element")
@Suppress("UNCHECKED_CAST")
return result as T
}
Run Code Online (Sandbox Code Playgroud)
NoSuchElementException当 Flow 完成发射但未发射单个元素时抛出该异常。我现在能想到的一种情况是,当你需要将集合转换为 Flow 源时。如果该集合为空并且您调用single该流程,您将得到一个NoSuchElementException.
这个例子可能看起来很荒谬,但你明白了:
val emptyListFlow = emptyList<Int>().asFlow()
launch {
val data = emptyListFlow.single()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3890 次 |
| 最近记录: |