От нескольких приостановленных функций Kotlin Coroutines к одной синхронной функции - PullRequest
1 голос
/ 25 марта 2019

Итак, у меня есть несколько suspended функций, которые выглядят так:

suspend fun getLatestCampaign(): List<Campaign> {
   return listOf()
}

suspend fun getRecommendedCampaign(): List<Campaign> {
   return listOf()
}

Так как я хочу запускать эти функции асинхронно, поэтому я сделал это так

val recommendedCampaignAsync = async(Dispatchers.IO) { getRecommendedCampaign() }
val latestCampaignAsync = async(Dispatchers.IO) { getLatestCampaign() }

И у меня также есть функция, которая будет обрабатывать результат этих асинхронных операций

fun displayCampaigns(campaigns: List<Campaign>) {}

Что мне делать, если я хочу каждый раз, когда выполняется одна из этих асинхронных операций, я хочу вызвать displayCampaigns и убедиться, что displayCampaigns выполняется синхронно. Поэтому я не хочу ждать завершения обеих этих асинхронных операций, а затем вызвать displayCampaigns

Ответы [ 2 ]

1 голос
/ 25 марта 2019
  1. async - это не инструмент для вашей работы, потому что вы хотите использовать результат синхронно.
  2. Dispatchers.IO не тот, который вы должны использовать, потому что вы вызываете приостановленные функции (которые я 'Предположим, что они не являются блокирующими, в противном случае они не должны быть объявлены как приостановленные).

То, что вы хотите, - это простейший случай: launch две сопрограммы в диспетчере Main, который должен ужебыли установлены по умолчанию:

class YourGuiClass : WhateverYourFrameworkWantsYouToExtend, CoroutineScope {
    override val coroutineContext = Job() + Dispatchers.Main

    fun refreshCampaigns() {
        launch {
            displayCampaigns(getRecommendedCampaign())
        }
        launch {
            displayCampaigns(getLatestCampaign())
        }
     }
}
0 голосов
/ 25 марта 2019

Либо вызовите displayCampaigns внутри блоков async

val recommendedCampaignAsync = async(Dispatchers.IO) {
    val campaigns = getRecommendedCampaign()
    displayCampaigns(campaigns)
}

val latestCampaignAsync = async(Dispatchers.IO) {
    val campaigns = getLatestCampaign()
    displayCampaigns(campaigns)
}

, либо добавьте CompletionHandler к заданиям, возвращаемым async

recommendedCampaignAsync.invokeOnCompletion{
    displayCampaigns(recommendedCampaignAsync.getCompleted())
}

latestCampaignAsync.invokeOnCompletion{
    displayCampaigns(latestCampaignAsync.getCompleted())
}
...