Как добиться параллелизма с соплинами Kotlin? - PullRequest
0 голосов
/ 06 июля 2019

У меня есть список каруселей, и я запускаю каждую карусель на основе карусели query Я выполняю fetchAssets (), а fetchAssets () - это приостановленная функция Kotlin, но проблема в том, что каждая функция вызывается, когда предыдущая завершена. Я хочудостичь совпадения?

 uiScope.launch {
 carousels.mapIndexed { index, carousel ->
when (val assetsResult = assetRepository.fetchAssets(carousel.query)) {
  is Response.Success<List<Asset>> -> {
    if (assetsResult.data.isNotEmpty()) {
      val contentRow = ContentRow(assetsResult.data)
      contentRows.add(contentRow)
      contentRowsmutableData.postValue(contentRows)
    }
  }
  is Response.Failure -> {
  }
}
}
}
override suspend fun fetchAssets(query: String): Response<List<Asset>> {

  return suspendCoroutine { cont ->doHttp(assetsEndpoint, JsonHttpCall("GET"),
        object : JsonReaderResponseHandler() {
          override fun onSuccess(jsonReader: JsonReader) {
              val apiAsset = ApiAssetList(jsonReader)
              cont.resume(Response.Success(apiAsset.items))
          }

          override fun onError(error: Error) {
            cont.resume(Response.Failure("errorMessage"))
          }
        })
  }
}```



1 Ответ

0 голосов
/ 06 июля 2019

Вы должны обернуть свою функцию приостановки в блок async, затем дождаться завершения всех асинхронных операций:

uiScope.launch {
    val asyncList = carousels.map { carousel ->
        async { assetRepository.fetchAssets(carousel.query) }
    }
    val results = asyncList.awaitAll()
    results.forEach { result ->
        when (result) {
            is Response.Success -> TODO()
            is Response.Failure -> TODO()
        }
    }
}
suspend fun fetchAssets(query: String): Response<List<Asset>>

Редактировать: если вы хотите обновить пользовательский интерфейс после каждого завершения, вам нужно изменить его следующим образом:

carousels.forEach { carousel ->
    uiScope.launch {
        val result = fetchAssets(carousel.query)
        when (result) {
            is Response.Success -> {
                if (result.data.isNotEmpty()) {
                    val contentRow = ContentRow(result.data)
                    contentRows.add(contentRow)
                    contentRowsmutableData.postValue(contentRows)
                }
            }
            is Response.Failure -> TODO()
        }
    }
}

Проверьте это для параллелизма с сопрограммами.

...