Reputation: 559
I'm fairly new to async development and specially coroutines. What I'm saying is basically that I don't even know if what I'm trying to achieve is possible or not.
I have a method called sendAudioMessage
that I want to return a string. Here is the (obfuscated) code:
override suspend fun sendAudioMessage(): String {
// ... Do some stuff
val listener: WebSocketUtils.Listener = object: WebSocketUtils.Listener {
// ... some (not relevant) functions
override fun onDisconnect(code: Int, reason: String?) {
//Do some stuff
return "myResult -> $code" //This obviously doesn't compile since is trying to make onDisconnect return a string instead of Unit
}
}
}
And then I want to call that like this:
override fun send(request: String) {
CoroutineScope(IO).launch {
val response = d.sendAudioMessage()
analyzeResponse( response, request )
}
}
Is this even possible? If so, how can I achieve this?
Upvotes: 3
Views: 2506
Reputation: 3745
You need to wrap your callbacks inside a suspendCancellableCoroutine
block in order to turn your blocking API call into a suspending function, so you can call it from a coroutine. It works like this:
suspend fun sendAudioMessage(): String = suspendCancellableCoroutine { continuation ->
WebSocketUtils.Listener {
// ... some (not relevant) functions
override fun onDisconnect(code: Int, reason: String?) {
//Do some stuff
when (code) {
OK -> continuation.resume("myResult -> $code")
ERROR -> continuation.resumeWithException(Exception(reason))
}
}
}
}
When your API call returns successfully you can return the result to your coroutine calling continuation.resume
with the result as argument.
When your API call returns with an error you can throw an exception calling continuation.resumeWithException
.
Now you can call sendAudioMessage
inside a coroutine and work with its result as usual:
class MyClass: CoroutineScope by CoroutineScope(Dispatchers.Default) {
...
override fun send(request: String) {
launch(Dispatchers.IO) {
val response = d.sendAudioMessage()
analyzeResponse(response, request)
}
}
...
}
Upvotes: 8