首页 > 解决方案 > foo().collect{...} 和 launch { foo().collect{...} } 有什么区别?

问题描述

Code A 得到 Result A , Code B 得到 Result B 。

1:是fun foo()协程吗?suspend如果它是协程函数,为什么不添加关键字?

2:在我看来,协程函数是使用launch {...}或者aync {...}如果fun foo()是协程函数,为什么main()代码B中的乐趣可以直接调用它?

3: Code A 和 Code B 有什么不同?

代码 A

fun main() = runBlocking<Unit> {    
    launch {
        for (k in 1..3) {
            println("I'm not blocked $k")
            delay(100)
        }
    }

    launch {
       foo().collect { value -> println(value) } 
    }   
}


fun foo(): Flow<Int> = flow { 
    for (i in 1..3) {
        delay(100) 
        emit(i+5) 
    }
}

结果 A

I'm not blocked 1
I'm not blocked 2
6
I'm not blocked 3
7
8

代码 B

fun main() = runBlocking<Unit> {    
    launch {
        for (k in 1..3) {
            println("I'm not blocked $k")
            delay(100)
        }
    }

    foo().collect { value -> println(value) } 

}


fun foo(): Flow<Int> = flow { 
    for (i in 1..3) {
        delay(100) 
        emit(i+5) 
    }
}

结果 B

I'm not blocked 1
6
I'm not blocked 2
7
I'm not blocked 3
8

标签: kotlinkotlin-coroutines

解决方案


foo函数不是挂起函数,因此您可以在协程范围之外调用它。此函数构建一个流并返回该流,但该流没有启动。该流程仅在您调用collect它时才开始,这是一个挂起函数,因此collect必须在协程范围内进行调用。 flows 是冷的,它们只有在您调用它们时才开始发出项目collect,因此构建流不是暂停功能,因为它是一种快速操作。


推荐阅读