假设我有一个这样的 API:
interface Foo {
val barFlow: Flow<Bar>
}
我像这样消费它:
class FooConsumer(private val foo: Foo) {
init {
CoroutineScope(Dispatchers.IO).launch {
val bar = foo.barFlow.single()
println("Collected bar: $bar)
}
}
}
根据文档,如果流为空,则可以抛出single
a 。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
}