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