如何在kotlin中实现Promise.all之类的功能

问题描述 投票:0回答:2

我尝试使用其 sdk 方法从 twillio 服务器获取消息,因此调用该方法时会返回回调以返回消息列表。我有对话列表,我想获取对话的所有消息,所以我像这样使用 forEach

  allConversations.forEach { conversation ->
            conversation.getMessageByIndex(conversation.lastMessageIndex){
                conversationLastMessages[conversation.sid] = it
            }
        }

所以我想等到所有listners都被执行然后想改变ui的状态。

android kotlin kotlin-coroutines coroutine coroutinescope
2个回答
3
投票

您可以并行发出所有请求,并等待所有请求完成以下后续步骤:

  1. 创建一个

    suspend
    函数
    getMessage
    ,它将负责暂停调用协程,直到执行请求。您可以使用
    suspendCoroutine
    suspendCancellableCoroutine
    来实现:

    suspend fun getMessage(conversation: Conversation) = suspendCoroutine<Message?> { continuation ->
        conversation.getMessageByIndex(conversation.lastMessageIndex, object : CallbackListener<Message> {
            override fun onError(errorInfo: ErrorInfo) {
                continuation.resume(null) // resume calling coroutine
                // or continuation.resumeWithException() depend whether you want to handle Exception or not
            }
    
            override fun onSuccess(result: Message) {
                continuation.resume(result) // resume calling coroutine
            }
        })
    }
    
  2. 使用

    async
    协程构建器和
    Dispatchers.IO
    调度程序并行运行请求,以从主线程卸载工作:

    async(Dispatchers.IO) {
        getMessage(conversation)
    }
    
  3. 要运行所有这些,您需要使用

    CoroutineScope
    的某个实例来启动协程。在
    ViewModel
    中,它可以是
    viewModelScope
    ,在
    Activity
    /
    Fragment
    -
    lifecycleScope
    。例如在
    ViewModel
    :

    viewModelScope.launch {
        val allConversations = ...
    
        allConversations.map { conversation ->
            async(Dispatchers.IO) {
                getMessage(conversation)
            }
        }.awaitAll() // waiting for all request to finish executing in parallel
         .forEach { message ->   // iterate over List<Message> and fill conversationLastMessages
             conversationLastMessages[message.getConversationSid()] = message
         }
    
         // here all requests are completed and UI can be updated
    }
    

0
投票

我写了一个promise库,在https://pro4j.com/

查看
© www.soinside.com 2019 - 2024. All rights reserved.