Flow的作用,我的理解上简称“异步处理并返回多个值”。
在这里,我使用的是AndroidStudio北极狐版本
依赖添加:
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.1'
平常得到多个值一般都是怎么做呢?
List:
fun testList() = runBlocking {
val list = listOf("1","2","3")
list.forEach { num ->
Log.e("TAG", num)
}
}
// 输出1,2,3
可以看到是一次返回了多个值,并不是异步的。”返回多个值但不是异步”
Sequence:
fun testSequence():Sequence<Int> = sequence {
for(i in 1..3){
Thread.sleep(1000) // 阻塞
yield(i) // 向序列中添加元素
}
}
fun main(){
testSequence().forEach { num->
Log.e(TAG, "$num")
}
}
// 间隔1s分别输出1,2,3
可以看到Thread.sleep(1000)是阻塞的。而如果想用delay函数,会发现有报错,但是yield(i)函数却是挂起的。可以看一下sequence的源码:
可以看到,sequence的参数传递的是一个SequenceScope的扩展函数,只是一个简单的函数,并没有被suspend,而再进去SequenceScope函数中可以看一下,yield函数是suspend的。关键的一点,在类头上有一个@RestrictsSuspension注解,这个注解的作用是限制挂起。也就是说,这个类不允许其他函数挂起,只允许调用本类中已有的挂起函数。
在此说明一件事,添加是异步的,但是在消费的时候却是同步的。也没有做到“异步处理并返回多个值”。
那这样的话,是不是可以用delay()加List?能这样想说明基础还不够,继续学吧。如果返回一个List,那么肯定是一次性返回多个数据。也无法做到“异步处理并返回多个值”。
通过Flow异步返回多个值
fun testFlow() = flow<Int> {
for (index in 1..3){
delay(1000)
emit(index) // 发射数据
}
}
fun main() = runBlocking {
testFlow().collect { num-> // 接收数据
Log.e(TAG, "main: $num")
}
}
// 间隔1s每次输出1,2,3
flow