fun main() {runBlocking {launch {flow4.collect{println("---collect-4")}println("---flow4")}}val flow4 = flow<Boolean>{delay(5000)emit(false)
}
我們分析下整個流程?
1.flow為什么之后在collect之后才會發送數據
2.collect的調用流程
我們先看創建flow的方法
public fun <T> flow(@BuilderInference block: suspend FlowCollector<T>.() -> Unit): Flow<T> = SafeFlow(block)
可以看見是一個方法,返回的是一個SafeFlow對象,然后把我們傳入?{
? ? ? delay(5000)
? ? ? ?emit(false)
}? ?表達式?的傳入到了這個對象中。
private class SafeFlow<T>(private val block: suspend FlowCollector<T>.() -> Unit) : AbstractFlow<T>() {override suspend fun collectSafely(collector: FlowCollector<T>) {collector.block()} }
然后,這個對象提供一個方法collectSafely,這個時候可以看到,要發送數據,必須得調用SafeFlow的collectSafely方法才行。
接下來我們分析下collect方法。看源碼發現需要傳入一個FlowCollector接口實現類
public suspend fun collect(collector: FlowCollector<T>)public fun interface FlowCollector<in T> {//注意這個emit方法public suspend fun emit(value: T) }
因為我們是使用flow方法返回的SafeFlow對象去調用的,所以我們看下SafeFlow的collect方法。SafeFlow是繼承AbstractFlow的類,所以我們看這個類就行
public abstract class AbstractFlow<T> : Flow<T>, CancellableFlow<T> {public final override suspend fun collect(collector: FlowCollector<T>) {//創建SafeCollector對象val safeCollector = SafeCollector(collector, coroutineContext)try {//調用實現類的collectSafely方法,把SafeCollector對象傳遞過去collectSafely(safeCollector)} finally {safeCollector.releaseIntercepted()}}public abstract suspend fun collectSafely(collector: FlowCollector<T>)
}
再接著查看collectSafely方法,發現調用到了我們傳入的閉包
private class SafeFlow<T>(private val block: suspend FlowCollector<T>.() -> Unit) : AbstractFlow<T>() {override suspend fun collectSafely(collector: FlowCollector<T>) {//調用我們傳入的閉包,而且他是FlowCollector的擴展函數collector.block()}
}
而我們傳入的閉包是suspend FlowCollector<T>.() -> Unit擴展函數,這個對象就是我們collect傳入的接口實現類,所以在
val flow4 = flow<Boolean>{
? ? ? delay(5000)
? ? ? ?emit(false)
}
方法中調用emit()實際就是調用collect傳入接口實現類的emit方法
?