Am trying to get messages from twillio server using its sdk method so on calling the method it return callback to return the List of messages. I have list of conversation,i want to get all messages for conversation so am using forEach like this
allConversations.forEach { conversation ->
conversation.getMessageByIndex(conversation.lastMessageIndex){
conversationLastMessages[conversation.sid] = it
}
}
So i want to wait until all listners get executed and then want to change the state of ui.
You can make all requests in parallel and wait for all of them to finish following next steps:
Create a suspend
function getMessage
, which will be responsible for suspending the calling coroutine until request is executed. You can use suspendCoroutine
or suspendCancellableCoroutine
for that:
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
}
})
}
Run requests in parallel using async
coroutine builder and Dispatchers.IO
dispatcher to offload work from the Main Thread:
async(Dispatchers.IO) {
getMessage(conversation)
}
To run all this you need to use some instance of CoroutineScope
to launch a coroutine. In ViewModel
it can be viewModelScope
, in Activity
/Fragment
- lifecycleScope
. For example in 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
}