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

Ali*_*tar 2 android kotlin android-viewmodel kotlin-coroutines

我正在使用 kotlin 协程从带有 viewmodel 的 android 中的服务器获取响应。问题是我想获得两个不同的请求响应来更新 ui 但想同时执行它们并等待它们都完成。然后使用收到的所有结果更新 ui。如果在每个请求之后使用 async 和 await 它将一一执行并且它不是并发的,如果使用请求映射和 awaitAll(),我无法处理多种数据类型(数据类),因为两个请求的数据类型不同. 可能不止两个请求。对于这种情况我该怎么办?

val job = viewModelScope.launch {

        val a = async { firstUseCase.execute() }.await()
        val b = async { secondUseCase.execute() }.await()
 }
Run Code Online (Sandbox Code Playgroud)

Gle*_*val 7

您只需要首先调用每个请求async以获得并发行为,然后await对于所有请求,无论您是一个接一个地单独执行还是使用awaitAll.

个人:

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
}
Run Code Online (Sandbox Code Playgroud)

或与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
}
Run Code Online (Sandbox Code Playgroud)

  • `awaitAll` 是可行的方法,但是如果 `resA` 和 `resB` 具有不同的类型,它们将简单地转换为 `Any` 并且您需要在代码中进行强制转换,这有点糟糕...... (11认同)

Ano*_*p M 5

您可以使用异步协程构建器和并行映射来并行运行动态 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]
Run Code Online (Sandbox Code Playgroud)