首页 > 解决方案 > What is the appropriate way of calling suspending functions inside a suspendCoroutine block?

问题描述

I need to call a suspending function inside a suspendCoroutine block, before I call continuation.resume(). What is the appropriate way of doing that?

private suspend fun someFunction() = suspendCoroutine { cont ->
    //...
    val myResult = mySuspendingFunction() //<--- The IDE says "Suspension functions can be called only within coroutine body"
    cont.resume(myResult)
}

标签: androidkotlinkotlin-coroutines

解决方案


You can't call a suspend function in suspendCoroutine block, because it accepts non suspend block as parameter:

suspend inline fun <T> suspendCoroutine(
    crossinline block: (Continuation<T>) -> Unit
): T

'suspendCoroutine' mainly used when we have some legacy code with callbacks, e.g.:

suspend fun getUser(id: String): User = suspendCoroutine { continuation ->
      Api.getUser(id) { user ->
          continuation.resume(user)
      }
}

If function someFunction() doesn't call Api with callbacks then you should reconsider your approach getting rid of 'suspendCoroutine':

private suspend fun someFunction() {
    // ...
    val myResult = mySuspendingFunction()
    // ...
}

If you still want to use suspendCoroutine move call of mySuspendingFunction out of suspendCoroutine block:

private suspend fun someFunction(): String {
    val myResult = mySuspendingFunction()

    return suspendCoroutine { cont ->
        //...
        cont.resume(myResult)
    }
}

suspend fun mySuspendingFunction(): String {
    delay(1000) // simulate request
    return "result"
}

推荐阅读