Flow的collect会阻塞执行吗?
Will the collect of the Flow block to execute?
我运行代码A,得到结果A,在我看来,应该是结果B。
似乎flow.collect { value -> println(value) }
块要执行。
Flow块的collect会执行吗?
代码A
fun simple(): Flow<Int> = flow {
println("Flow started")
for (i in 1..3) {
delay(300)
emit(i)
}
}
fun main() = runBlocking<Unit> {
println("Calling simple function...")
val flow = simple()
println("Calling collect...")
flow.collect { value -> println(value) } //Block?
println("Calling collect again...")
}
结果A
Calling simple function...
Calling collect...
Flow started
1
2
3
Calling collect again...
结果B
Calling simple function...
Calling collect...
Flow started
Calling collect again...
1
2
3
顺便说一句,我 运行 代码 1 并得到我预期的结果 1。
代码 1
fun simple(): Flow<Int> = flow {
for (i in 1..3) {
delay(100)
emit(i)
}
}
fun main() = runBlocking<Unit> {
launch {
for (k in 1..3) {
println("I'm not blocked $k")
delay(100)
}
}
simple().collect { value -> println(value) }
}
结果 1
I'm not blocked 1
1
I'm not blocked 2
2
I'm not blocked 3
3
挂起函数不会阻塞,但它们是同步的,这意味着协程中代码的执行在继续之前等待挂起函数return。挂起函数调用和阻塞函数调用的区别在于,协程等待挂起函数到return.
时,线程被释放用于其他任务。
collect
是一个挂起函数,它在内部重复和同步地调用它的 lambda(挂起,而不是阻塞)并且不会 return 直到 Flow 完成。
launch
是一个启动协程的异步函数。它 return 立即执行,而无需等待其协程完成,这就是代码 1 表现如您预期的原因。
我运行代码A,得到结果A,在我看来,应该是结果B。
似乎flow.collect { value -> println(value) }
块要执行。
Flow块的collect会执行吗?
代码A
fun simple(): Flow<Int> = flow {
println("Flow started")
for (i in 1..3) {
delay(300)
emit(i)
}
}
fun main() = runBlocking<Unit> {
println("Calling simple function...")
val flow = simple()
println("Calling collect...")
flow.collect { value -> println(value) } //Block?
println("Calling collect again...")
}
结果A
Calling simple function...
Calling collect...
Flow started
1
2
3
Calling collect again...
结果B
Calling simple function...
Calling collect...
Flow started
Calling collect again...
1
2
3
顺便说一句,我 运行 代码 1 并得到我预期的结果 1。
代码 1
fun simple(): Flow<Int> = flow {
for (i in 1..3) {
delay(100)
emit(i)
}
}
fun main() = runBlocking<Unit> {
launch {
for (k in 1..3) {
println("I'm not blocked $k")
delay(100)
}
}
simple().collect { value -> println(value) }
}
结果 1
I'm not blocked 1
1
I'm not blocked 2
2
I'm not blocked 3
3
挂起函数不会阻塞,但它们是同步的,这意味着协程中代码的执行在继续之前等待挂起函数return。挂起函数调用和阻塞函数调用的区别在于,协程等待挂起函数到return.
时,线程被释放用于其他任务。collect
是一个挂起函数,它在内部重复和同步地调用它的 lambda(挂起,而不是阻塞)并且不会 return 直到 Flow 完成。
launch
是一个启动协程的异步函数。它 return 立即执行,而无需等待其协程完成,这就是代码 1 表现如您预期的原因。