简体   繁体   English

Kotlin 协程等待 2 个或更多不同的并发请求

[英]Kotlin coroutines await for 2 or more different concurrent requests

I'm using kotlin coroutines to get responses from server in android with viewmodel.我正在使用 kotlin 协程通过 viewmodel 从 android 中的服务器获取响应。 The problem is that i want to get two different requests responses to update ui but wanna execute them concurrently and wait for both of them to finish.问题是我想获得两个不同的请求响应来更新 ui 但想同时执行它们并等待它们完成。 then update the ui with all of the result received.然后使用收到的所有结果更新 ui。 If using async and await after each request it will execute one by one and it's not concurrent and if using map of requests and awaitAll(), i can't handle multiple data types (data classes) because the data types of two requests are different.如果在每个请求之后使用 async 和 await 它将一个一个地执行并且它不是并发的,如果使用请求的 map 和 awaitAll(),我无法处理多个数据类型(数据类),因为两个请求的数据类型不同. It could be more that two requests.可能不止两个请求。 What can i do for this situation?这种情况我该怎么办?

val job = viewModelScope.launch {

        val a = async { firstUseCase.execute() }.await()
        val b = async { secondUseCase.execute() }.await()
 }

You just need to start every request first calling async in order to get a concurrent behavior and then await for all of them no matter if you do it individually one after another or all of them at once with awaitAll .您只需启动每个请求,首先调用async以获得并发行为,然后await所有请求,无论您是一个接一个地单独执行,还是使用awaitAll一次执行所有请求。

Individually:个别:

viewModelScope.launch {
    val a = async { firstUseCase.execute() }
    val b = async { secondUseCase.execute() }

    val resA = a.await()
    val resB = b.await()

    //Use results 'resA' and 'resB' here
}

Or with awaitAll :或使用awaitAll

viewModelScope.launch {
    val a = async { firstUseCase.execute() }
    val b = async { secondUseCase.execute() }

    val (resA, resB) = awaitAll(a, b)

    //Use results 'resA' and 'resB' here
}

You could use async coroutine builder along with a parallel map to run dynamic bg works parallel and suspend further execution until all the results are available -您可以使用异步协程构建器和并行 map 并行运行动态 bg 工作并暂停进一步执行,直到所有结果都可用 -

import kotlinx.coroutines.*

fun main() {
  runBlocking<Unit>
     {
       val smoothie = prepareSmoothie()
       println("prepareSmoothie | Smoothie prepared with: $smoothie")
     }
}

private suspend fun addIngredient(index: Int, item: String): String {
  println("prepareSmoothie | addIngredient: $item")
  delay(index.times(3_000).toLong())
  println("prepareSmoothie | addedIngredient: $item")
  return "$item"
}

private suspend fun prepareSmoothie(): List<String> {
  println("prepareSmoothie | Go On")
  println("++++++++++++++++++++++")
  return runBlocking {
      listOf("Fruits", "Grains", "Flavor boosters", "Ice").mapIndexed { index, item ->
        async {
          addIngredient(index, item)
        } .map { it.await() }
   }
}
  
Result:
  
prepareSmoothie | Go On
++++++++++++++++++++++
prepareSmoothie | addIngredient: Fruits
prepareSmoothie | addIngredient: Grains
prepareSmoothie | addIngredient: Flavor boosters
prepareSmoothie | addIngredient: Ice
++++++++++++++++++++++
prepareSmoothie | addedIngredient: Fruits
prepareSmoothie | addedIngredient: Grains
prepareSmoothie | addedIngredient: Flavor boosters
prepareSmoothie | addedIngredient: Ice
++++++++++++++++++++++
prepareSmoothie | Smoothie prepared with: [Fruits, Grains, Flavor boosters, Ice]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM