我尝试使用其 sdk 方法从 twillio 服务器获取消息,因此调用该方法时会返回回调以返回消息列表。我有对话列表,我想获取对话的所有消息,所以我像这样使用 forEach
allConversations.forEach { conversation ->
conversation.getMessageByIndex(conversation.lastMessageIndex){
conversationLastMessages[conversation.sid] = it
}
}
所以我想等到所有listners都被执行然后想改变ui的状态。
您可以并行发出所有请求,并等待所有请求完成以下后续步骤:
创建一个
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
}
})
}
使用
async
协程构建器和 Dispatchers.IO
调度程序并行运行请求,以从主线程卸载工作:
async(Dispatchers.IO) {
getMessage(conversation)
}
要运行所有这些,您需要使用
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
}
我写了一个promise库,在https://pro4j.com/
查看