我对异步开发和协程特别陌生。我要说的基本上是,我什至不知道我要实现的目标是否可行。
我有一个名为sendAudioMessage
的方法,我想返回一个字符串。这是(模糊的)代码:
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
}
}
}
然后我要这样称呼:
override fun send(request: String) {
CoroutineScope(IO).launch {
val response = d.sendAudioMessage()
analyzeResponse( response, request )
}
}
这甚至可能吗?如果是这样,我该如何实现?
答案 0 :(得分:2)
您需要将回调包装在suspendCancellableCoroutine
块中,以便将您的阻塞API调用转换为挂起函数,以便可以从协程调用它。它是这样的:
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))
}
}
}
}
当API调用成功返回时,您可以将结果返回给协程调用continuation.resume
,并将结果作为参数。
当您的API调用返回错误时,您可以引发调用continuation.resumeWithException
的异常。
现在您可以在协程中调用sendAudioMessage
并照常使用其结果:
class MyClass: CoroutineScope by CoroutineScope(Dispatchers.Default) {
...
override fun send(request: String) {
launch(Dispatchers.IO) {
val response = d.sendAudioMessage()
analyzeResponse(response, request)
}
}
...
}