Будет ли сбор блока потока выполняться?

#kotlin #kotlin-coroutines

Вопрос:

Я запускаю код A и получаю результат A. На мой взгляд, это должен быть результат Б.

Похоже, что flow.collect { value -> println(value) } блок нужно выполнить.

Будет ли сбор блока потока выполняться ?

Код А

 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...")   
}
 

Результат А

 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
 

Ответ №1:

Функции приостановки не блокируются, но они синхронны, что означает, что выполнение кода в сопрограмме ожидает возвращения функции приостановки, прежде чем продолжить. Разница между вызовами функции приостановки и вызовами функции блокировки заключается в том, что поток освобождается для использования в других задачах, пока сопрограмма ожидает возврата функции приостановки.

collect является функцией приостановки, которая внутренне повторно и синхронно вызывает свой лямбда-код (приостановка, а не блокировка) и не возвращается, пока поток не будет завершен.

launch является асинхронной функцией, запускающей сопрограмму. Он возвращается немедленно, не дожидаясь завершения сопрограммы, поэтому код 1 вел себя так, как вы ожидали.