您的位置:首页 > 房产 > 家装 > 灯饰如何做网站推广_查询网域名查询_企业如何进行网络推广_百度搜索关键词设置

灯饰如何做网站推广_查询网域名查询_企业如何进行网络推广_百度搜索关键词设置

2025/5/5 3:32:06 来源:https://blog.csdn.net/xueyoubangbang/article/details/147597497  浏览:    关键词:灯饰如何做网站推广_查询网域名查询_企业如何进行网络推广_百度搜索关键词设置
灯饰如何做网站推广_查询网域名查询_企业如何进行网络推广_百度搜索关键词设置
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方法


 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com