В чем разница между foo (). Collect {...} и запуском {foo (). Collect {...}}? - PullRequest
0 голосов
/ 04 апреля 2020

Код A получает результат A, а код B - результат B.

1: являются ли сопрограммы fun foo()? почему он не добавляет ключевое слово suspend раньше, если это функция сопрограмм?

2: На мой взгляд, функция сопрограмм запускается с использованием launch {...} или aync {...}, если fun foo() является функцией сопрограмм почему main() удовольствие в коде B может вызывать его напрямую?

3: в чем различия между кодом A и кодом 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

Ответы [ 2 ]

2 голосов
/ 04 апреля 2020

1: Веселые сопрограммы foo ()? почему он не добавляет ключевое слово suspend раньше, если это функция сопрограммы?

На самом деле foo() - это обычная функция, которая возвращает поток.

2: В моем учтите, что функция сопрограмм запускается с помощью launch {...} или ayn c {...}, если fun foo () является функцией сопрограмм, почему функция main () в Code B может вызывать ее напрямую?

Также используются runBlocking{...}, runBlockingTest{...}, produce{...} и actor{...}. Неважно, где вы создаете / создаете / объявляете поток, важно, где вы вызываете операторы терминала (например, collect), которые приостанавливают функции и должны вызываться внутри сопрограммы или внутри другой функции приостановки. Кстати, вы используете все основные методы внутри сопрограммы, поскольку вы заключаете ее в блок runBlocking.

3: В чем разница между кодом A и кодом B?

Нет. Вы просто создаете другую сопрограмму в коде А, которая также будет работать в основном потоке.

2 голосов
/ 04 апреля 2020

Функция foo не является функцией приостановки, поэтому вы можете вызывать ее вне области сопрограмм. Эта функция создает поток и возвращает поток, но поток не запускается. Поток запускается только тогда, когда вы вызываете collect для него, и это приостанавливает функцию, поэтому вызов collect должен выполняться в области сопрограмм. flow s холодные, они начинают испускать элементы только тогда, когда вы вызываете collect, поэтому создание потока не является функцией приостановки, потому что это быстрая операция.

...