Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

340
Views
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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!