Please see the code below, the main function with suspend modifier works fine, but when ran with run blocking the await behaves prematurely and the Result is returned with the coroutine object instead of actual value.
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
typealias SuspendingResultFunction<T, A> = suspend (T) -> Result<A>
suspend fun <T, R> Result<T>.then(transform: SuspendingResultFunction<T, R>): Result<R> {
return if (this.isSuccess) transform(this.getOrNull()!!)
else Result.failure(this.exceptionOrNull()!!)
}
private suspend fun suspendingFunction(no: Int): Result<Int> {
val plusOneTask = CoroutineScope(Dispatchers.Default).async { delayedPlusOne(no) }
val plusOne = plusOneTask.await()
return Result.success(plusOne)
}
private suspend fun delayedPlusOne(no: Int): Int {
delay(1000L)
return no + 1
}
suspend fun main_with_suspend_works_good() {
val threeResult = suspendingFunction(1).then { suspendingFunction(it) }
val three = threeResult.getOrNull()
println(three)
}
fun main() {
runBlocking {
val threeResult = suspendingFunction(1).then { suspendingFunction(it) }
val three = threeResult.getOrNull()
println(three)
// above line throws the exception, once the execution reach to await.
// : class kotlin.coroutines.intrinsics.CoroutineSingletons cannot be cast to class java.lang.Number (kotlin.coroutines.intrinsics
}
// When we use junit for testing we suppose to use runBlocking !!
// But even why runBlocking does not work ?
}