Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asynchronous 如何使用协程传递结果?_Asynchronous_Kotlin_Coroutine_Kotlin Coroutines - Fatal编程技术网

Asynchronous 如何使用协程传递结果?

Asynchronous 如何使用协程传递结果?,asynchronous,kotlin,coroutine,kotlin-coroutines,Asynchronous,Kotlin,Coroutine,Kotlin Coroutines,假设我有一份回购清单。我想对它们进行迭代。由于每次回购都会返回结果,所以我想将其传递下去 val repos = listOf(repo1, repo2, repo3) val deferredItems = mutableListOf<Deferred<List<result>>>() repos.forEach { repo -> deferredItems.add(async { getResult(repo) }) } val res

假设我有一份回购清单。我想对它们进行迭代。由于每次回购都会返回结果,所以我想将其传递下去

val repos = listOf(repo1, repo2, repo3)
val deferredItems = mutableListOf<Deferred<List<result>>>()

repos.forEach { repo ->
    deferredItems.add(async { getResult(repo) })
}

val results = mutableListOf<Any>()
deferredItems.forEach { deferredItem ->
    results.add(deferredItem.await())
}

println("results :: $results")
val repos=listOf(repo1、repo2、repo3)
val deferredItems=mutableListOf()
repos.forEach{repo->
add(异步{getResult(repo)})
}
val results=mutableListOf()
deferredItems.forEach{deferredItem->
results.add(deferredItem.await())
}
println(“结果:$results”)
在上述情况下,它等待每个回购返回结果。它按顺序填充
结果
,结果是
repo1
,结果是
repo2
。如果
repo1
repo2
花费更多的时间返回结果,我们将等待
repo1
的结果,即使我们有
repo2
的结果


有没有办法在我们得到结果后立即传递
repo2
的结果?

这就是频道的用途:

val repos = listOf("repo1", "repo2", "repo3")
val results = Channel<Result>()
repos.forEach { repo ->
    launch {
        val res = getResult(repo)
        results.send(res)
    }
}

for (r in results) {
    println(r)
}

Flow
API几乎直接支持这一点:

repos.asFlow()
        .flatMapMerge { flow { emit(getResult(it)) } }
        .collect { println(it) }

flatMapMerge
首先收集从传递给它的lambda中流出的所有
流,然后同时收集这些流,并在其中任何一个流完成后将其发送到下游。

您应该使用
通道

suspend fun loadReposConcurrent() = coroutineScope {
    val repos = listOf(repo1, repo2, repo3)
    val channel = Channel<List<YourResultType>>()

    for (repo in repos) {
        launch {
            val result = getResult(repo)
            channel.send(result)
        }
    }

    var allResults = emptyList<YourResultType>()
    repeat(repos.size) {
        val result = channel.receive()
        allResults = allResults + result

        println("results :: $result")
        //updateUi(allResults)
    }
}
suspend fun loadReposConcurrent()=coroutineScope{
val repos=列表(repo1、repo2、repo3)
val通道=通道()
用于(回购中的回购){
发射{
val结果=getResult(回购)
频道发送(结果)
}
}
var allResults=emptyList()
重复(回购规模){
val结果=通道。接收()
所有结果=所有结果+结果
println(“结果:$result”)
//更新(所有结果)
}
}
在上面的代码中,
for(repo in repos){…}
循环在seprate corroutines中计算的所有请求,并与
launch
一起启动,一旦它们的结果就绪,将发送到
频道

repeat(repos.size){…}
中,
channel.receive()
等待来自所有协程的新值并使用它们

suspend fun loadReposConcurrent() = coroutineScope {
    val repos = listOf(repo1, repo2, repo3)
    val channel = Channel<List<YourResultType>>()

    for (repo in repos) {
        launch {
            val result = getResult(repo)
            channel.send(result)
        }
    }

    var allResults = emptyList<YourResultType>()
    repeat(repos.size) {
        val result = channel.receive()
        allResults = allResults + result

        println("results :: $result")
        //updateUi(allResults)
    }
}