Kotlin: применить функцию приостановки к списку «параллельно»? - PullRequest
1 голос
/ 02 августа 2020

Если у меня есть List<A> и функция suspend (A) -> B, как я могу применить эту функцию к списку параллельно?

Ответы [ 2 ]

1 голос
/ 02 августа 2020

Вы можете создать функцию расширения для CoroutineScope, go через каждый элемент списка и запустить сопрограмму для каждого элемента. Таким образом элементы списка будут обрабатываться параллельно. Некоторый фрагмент кода:

fun CoroutineScope.processListInParallel(list: List<A>): List<Deferred<B>> = list.map {
    async { // launch a coroutine
        processA(it)
    }
}

GlobalScope.launch {
    val list = listOf(A("name1"), A("name2"), A("name3"))
    val deferredList = processListInParallel(list)
    val results: List<B> = deferredList.awaitAll() // wait for all items to be processed
}

suspend fun processA(a: A): B {
    delay(1000) // emulate suspension
    return B("Result ${a.name}")
} 

data class A(val name: String) {}
data class B(val name: String) {}

Примечание : GlobalScope используется здесь в качестве примера, его использование крайне не рекомендуется , код приложения обычно должен использовать приложение -определенный CoroutineScope.

0 голосов
/ 03 августа 2020
coroutineScope {
    list.map {
        async {
            process(it)
        }
    } // List<Deferred<B>>
    .awaitAll() // List<B>
}

suspend fun process(a: A): B {
   ...
}

Предполагается, что вы уже находитесь в контексте suspend. В противном случае вам нужно запустить новую сопрограмму в соответствующей области вместо использования функции coroutineScope scoping.

...