协程中Flow的一些特性(冷流,流的连续型、构建器、上下文、指定协程中收集流、流的取消)

本文介绍了Kotlin中的冷流概念,包括其惰性生成特性,以及流的连续性、构建器、上下文切换、在指定协程中收集和取消机制。通过实例展示了如何在实际开发中运用这些特性。
摘要由CSDN通过智能技术生成

一、冷流

Flow是一种类似序列的冷流,flow构建器中的代码知道流被收集的时候才运行。

惰性生成: 冷流只有在被订阅时才会开始生成数据。在订阅之前,它不会执行任何操作,也不会产生任何数据项。

简单来讲就是现学现用,什么时候使用什么时候才调用。比如使用collect就是启动的标志。

    suspend fun coldFlow() = flow{
        println("Flow started")
        for (i in 1..3){
            delay(1000)
            emit(i)//用于产生元素的
        }
    }

    @Test
    fun testcoldFlow() = runBlocking {
        val flow = coldFlow()
        println("Starting collect...")
        flow.collect{ value -> println(value)}
        println("Starting collect again...")
        flow.collect{ value -> println(value)}
    }

运行结果可以看到,当运行到val flow = coldFlow(),这个函数并没有进行调用(没有打印Flow start),而是到调用flow.collect时才进行打印。

二、流的连续性

这很容易理解的,就是Flow收集的元素是按照顺序执行的,像水一样,先流进来就先出去,再一个关键就是这个连续性,对数据传输十分重要。

三、流的构建器

最典型的时flow 构建,除此之外还有:

四、流的上下文

就是说流的创建和收集使用同一个上下文(在同一线程里),并且不能强制更改(除非使用flowOn),例如:

没有使用flowOn:

 suspend fun contextFlow1() = flow{
        println("Flow started ${Thread.currentThread().name}")
        for (i in 1..3){
            delay(1000)
            emit(i)//用于产生元素的
        }
    }
    @Test
    fun testcontextFlow1() = runBlocking {
        contextFlow1().collect{
            value -> println("Collected $value ${Thread.currentThread().name}")
        }
    }

我们可以看到,其中的都是main主线程,而且在同一上下文,但是这并不符合我们实际开发需求,有时流的构建与收集并非在同一上下文里,此时我们需要使用flowOn

 suspend fun contextFlow1() = flow{
        println("Flow started ${Thread.currentThread().name}")
        for (i in 1..3){
            delay(1000)
            emit(i)//用于产生元素的
        }
    }.flowOn(Dispatchers.Default)
    @Test
    fun testcontextFlow1() = runBlocking {
        contextFlow1().collect{
            value -> println("Collected $value ${Thread.currentThread().name}")
        }
    }

 

这样就可以了。

五、在指定协程中收集流

就是说我们收集的流不在本线程调用了(collect),而是交给其他协程去调用,这在实际开发中也经常使用,这时要使用launchln

   fun event() = (1..3)
        .asFlow()
        .onEach { delay(1000) }
        .flowOn(Dispatchers.Default)
    @Test
    fun textflowLaunchIn() = runBlocking { 
        event().onEach { event -> println("Event: $event ${Thread.currentThread().name}" ) }
            .launchIn(CoroutineScope((Dispatchers.IO)))
            .join()
    }

可见,这交给了后台线程去处理

六、流的取消

1.流会随着所在的协程取消而取消

2.

就是说一般的流操作可以取消的,比如使用cancel

但是呢。像asFlow这种流构建器不会执行取消操作,这时你想取消得使用cancelable

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Imagine8877

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值