Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

341
Visualizações
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)
}
over 4 years ago · Hanz Gallego
2 Respostas
Responde à pergunta

0

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"
}
over 4 years ago · Hanz Gallego Relatório

0

It's best to avoid this and call the suspending function before suspendCoroutine, as others have answered. That is possible for the specific case in question.

However, that is not possible if you need the continuation.

(The following is for those, who found this question for the this reason, as @Zordid and I have. chan.send is an example of this.)

In which case, the following is a possible, but error prone way to do it, that I do not recommend:

suspend fun cont1() {
    //btw. for correct implementation, this should most likely be at least suspendCancellableCoroutine
    suspendCoroutine<Unit> { uCont ->
        val x = suspend { chan.send(foo(uCont)) }
        x.startCoroutine(Continuation(uCont.context) {
            if (it.isFailure)
                uCont.resumeWith(it)
            // else resumed by whatever reads from chan
        })
    }
}

(I think the error handling alone illustrates why it's not a great option, despite other problems.)

A better, safer and cheaper way is to use CompletableDeferred if you can.

If you must pass in a Continuation, it's still safer and probably cheaper to do:

suspend fun cont2() {
    val rslt = CompletableDeferred<Unit>()
    chan.send(foo(Continuation(currentCoroutineContext()) {
        rslt.completeWith(it)
    }))
    rslt.await()
}
over 4 years ago · Hanz Gallego Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda