Flow的作用,我的理解上简称“异步处理并返回多个值”
    在这里,我使用的是AndroidStudio北极狐版本
    image.png
    依赖添加:

    1. implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1'
    2. 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的源码:
    image.png
    image.png
    可以看到,sequence的参数传递的是一个SequenceScope扩展函数,只是一个简单的函数,并没有被suspend,而再进去SequenceScope函数中可以看一下,yield函数是suspend的。关键的一点,在类头上有一个@RestrictsSuspension注解,这个注解的作用是限制挂起。也就是说,这个类不允许其他函数挂起,只允许调用本类中已有的挂起函数。
    image.png
    在此说明一件事,添加是异步的,但是在消费的时候却是同步的。也没有做到“异步处理并返回多个值”。

    那这样的话,是不是可以用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{}是属于flow的一个构建器,testFlow()函数构建了一个flow,这个函数在函数中异步的去emit()数据,然后在调用处拿到同一个构建对象,一定是同一个构建对象,调用collect函数去收集这个构建对象emit()的数据。可以看到每间隔1s分别输出1,2,3。另外,flow构建的代码块中的函数可以挂起,表明testFlow()这个函数可以不用加suspend修饰符,delay(),emit()函数都被suspend修饰了。emit()函数用来发射数据,collect()函数用来接收发射过来的数据。