George
02/06/2022, 3:21 PMNick Allen
02/06/2022, 6:03 PMawait
in a totally different context than the async
lambda. Just be aware that the coroutineScope
builder will not return until the result is ready because of structured concurrency.
Seems like an odd thing to do to me. What’s the use case?George
02/07/2022, 8:45 AMNick Allen
02/07/2022, 5:36 PMGeorge
02/21/2022, 7:50 AM@RestController
class TestApi {
@GetMapping(value = ["test", "/test"])
suspend fun test(response: ServerHttpResponse): FakeResponse = coroutineScope {
val responseDeferred = async {
return@async acceptResponse()
}
return@coroutineScope responseDeferred.await()
}
@GetMapping(value = ["test2", "/test2"])
suspend fun test2(response: ServerHttpResponse): FakeResponse {
val fakeResponseDeferred = acceptResponseAsync()
return fakeResponseDeferred.await()
}
@GetMapping(value = ["test2", "/test2"])
suspend fun test3(response: ServerHttpResponse): FakeResponse {
val fakeResponseDeferred = acceptDeferredResponse()
return fakeResponseDeferred
}
suspend fun acceptResponse(): FakeResponse {
return FakeResponse("Hello From test")
}
suspend fun acceptResponseAsync(): Deferred<FakeResponse> = coroutineScope {
async {
return@async FakeResponse("Hello async From test")
}
}
suspend fun acceptDeferredResponse(): FakeResponse = coroutineScope {
async {
return@async FakeResponse("Hello pretend we are doing some async heavy stuff")
}
}.await()
}
Nick Allen
02/21/2022, 8:29 AMcoroutineScope
won't return until async
is done. This is part of structured concurrency. Parent jobs don't finish until child jobs are all complete. So returning the Deferred
outside of coroutineScope
is pointless, since it is already complete. You can just return the value.
The point of coroutineScope
is so that you can launch multiple coroutines for concurrency inside a regular suspend method but still easily adhere to the principle that suspend methods finish all their work before they return. This is why coroutineScope
waits for all children. If you want to return a Deferred
that is not complete, then you should not use a suspend method and instead should use a non-suspend method that takes a CoroutineScope
as a parameter (or as the receiver) and call async/launch
on the provided CoroutineScope
.George
02/21/2022, 10:01 AM