从多个Kotlin协程暂停函数到单个同步函数

从多个Kotlin协程暂停函数到单个同步函数,kotlin,kotlin-coroutines,Kotlin,Kotlin Coroutines,因此,我有多个挂起的函数,如下所示 suspend fun getLatestCampaign(): List<Campaign> { return listOf() } suspend fun getRecommendedCampaign(): List<Campaign> { return listOf() } val recommendedCampaignAsync = async(Dispatchers.IO) { getRecommendedCa

因此,我有多个
挂起的
函数,如下所示

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>) {}
fun显示活动(活动:列表){
如果我想在每次异步操作完成时调用
displaymagainments
,并确保同步执行
displaymagainments
,我该怎么办。
因此,我不想等待这两个异步操作完成,然后调用
displayCampaigns

async
块内调用
displayCampaigns

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

val latestCampaignAsync = async(Dispatchers.IO) {
    val campaigns = getLatestCampaign()
    displayCampaigns(campaigns)
}
或者向异步返回的作业添加一个
CompletionHandler

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

latestCampaignAsync.invokeOnCompletion{
    displayCampaigns(latestCampaignAsync.getCompleted())
}
  • async
    不是作业的工具,因为您希望同步使用结果
  • Dispatchers.IO
    不是您应该使用的函数,因为您调用了suspendable函数(我假设这些函数是非阻塞的,否则它们不应该被声明为suspendable)
  • 您需要的是最简单的情况:
    launch
    Main
    dispatcher中启动两个协程,这两个协程应该已经设置为默认协程:

    class YourGuiClass : WhateverYourFrameworkWantsYouToExtend, CoroutineScope {
        override val coroutineContext = Job() + Dispatchers.Main
    
        fun refreshCampaigns() {
            launch {
                displayCampaigns(getRecommendedCampaign())
            }
            launch {
                displayCampaigns(getLatestCampaign())
            }
         }
    }
    

    为了记录日志,在返回之前在每个异步块中调用
    displaycamp()
    ,这不是导致争用条件吗。假设异步操作同时完成,它们也将同时执行
    displaycamp
    。我说的对吗?
    getLatestCampaign()
    getRecommendedCampaign()
    可以是正常的函数<在此上下文中不需要代码>挂起
    。感谢您的回答。是否有可能在比赛条件下使用
    displayCampaigns
    ?假设这些异步操作同时完成。可以由两个线程同时调用Yes
    displayCampaigns
    。因此,您必须确保此函数是线程安全的。如果此
    displayCampaigns
    将改变共享状态,是否安全?因为您是在主(GUI)线程上启动它的,因此不涉及多线程。但是,在遇到挂起点时,您仍应小心不要让共享状态保持半更新状态。很抱歉,我没有提供更多上下文,我为什么对
    getRecommendedCampaigns
    getLatestCampaigns
    使用
    suspend
    ,因为这是一种改装(网络操作)函数,所以它是一个阻塞函数。这就是为什么我让它与Dispatchers.IO异步的原因。那你就错了。如果您计划使用普通的旧阻塞函数,那么不要声明它们
    suspend
    。事实上,在这种情况下根本不要使用协同程序,因为它们不会给您带来任何好处。