Return value from coroutine scope without runBlocking

Viewed 2146

I am trying to run a function based on the response data of a repo call, and running into an issue with race conditions / returning data using coroutine scope. Based on the two pseudo code blocks, I was wondering if I could get some help?

Option 1: Can't return a response within a coroutine scope without using runBlocking.

fun mainFunction(): Boolean {
  return subFunction(getResponse()) //returns boolean
}

private fun getResponse () {
  scope.launch{
    val response = async { someApiCall }.await()

    return response
  }
}

Option 2: The response value is not initialized by the time the subFunction is called, thus leading to an error.

lateinit var response: MutableList<>

fun mainFunction(): Boolean {
  return subFunction(response) //returns boolean
}

private fun getResponse () {
  scope.launch{
    response = async { someApiCall }.await()
  }
}
1 Answers

Case 1: Main function returns something

suspend fun mainFunction(): Boolean = subFunction(getResponse())

fun subFunction(input: Response): Boolean {
    // Do something
    return something
}

suspend fun getResponse() = withContext(Dispatchers.IO) {
    someApiCall()
}

Then the caller of mainFunction is kick-and-forget, we can use scope.launch.

fun metaMainFunction() {
    scope.launch {
        val isSomething = mainFunction()
        // Do something with isSomething
    }
}

Case 2: mainFunction is kick-and-forget, we apply the same behavior to metaMainFunction of case 1

fun mainFunction() {
    scope.launch {
        val response = getResponse()
        // Do something with response
    }
}

The best practice is the callee should decide which thread it is executed. In this case, we should always use withContext(Dispatchers.IO) for getResponse().

Related