kotlin - 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
解决方案
该foo
函数不是挂起函数,因此您可以在协程范围之外调用它。此函数构建一个流并返回该流,但该流没有启动。该流程仅在您调用collect
它时才开始,这是一个挂起函数,因此collect
必须在协程范围内进行调用。
flow
s 是冷的,它们只有在您调用它们时才开始发出项目collect
,因此构建流不是暂停功能,因为它是一种快速操作。
推荐阅读
- python - 当我尝试以不和谐的方式向我的机器人发送消息时,消息未传递
- python - Django - 加载css的问题
- typescript - TypeScript - 基于类型对象在函数 sig 中映射键类型和值类型
- html - 我想要一个除此之外还有一个按钮的输入
- blazor - Blazor Webassembly 来回导航初始化
- laravel - Laravel forge 服务器断开连接
- linux - 在 Bash 中执行音译字符串
- python - 比较两个熊猫数据框以查找字数
- windows - 如何在 Windows 中验证 PE 文件的数字签名并找到签名者?(使用 C/C++)
- c++ - 使用 C++ 将自定义过滤器应用于 RECT 后面的所有内容,a'la CSS 背景过滤器样式