Отличная статья, огромный объем работ проделан. Но возник вопрос по этому примеру и пришлось смотреть сорсы.
/*
Dispatchers.Main всегда переключает выполнение корутины
на главный поток через Handler.post() механизм,
даже если корутина и так выполняется на главном
*/
val uiScope = CoroutineScope(Dispatchers.Main + Job())
uiScope.launch {
launch {
println("I'm child coroutine #1")
}
launch {
println("I'm child coroutine #2")
}
println("I'm parent coroutine")
}
В этом примере возникает вопрос, а как в итоге завершится parent coroutine, если во время ее resumeWith дочерние корутины еще не завершены и она завершиться не может.
Как и кто в итоге вызовет ее resumeWith, учитывая что вы упомянули что дочерние корутины не знают про ее continuation?
Объект Continuation родительской корутины никак не связан с Continuation объектами дочерних корутин, поэтому когда завершатся последние результат не будет проброшен обратно в UiScopeParentBlock, да и в этом особо нет смысла, как например с withContext(), который гарантирует последовательный порядок выполнения с возвращением результата.
Ответом будет подписка на Job дочерних корутин, которая как раз и вызовет метод финализации стейта нашей корутины при последнем onCompletion. При этом resumeWith не будет вызван повторно, но стейт корутины корректно финализируется
private tailrec fun tryWaitForChild(state: Finishing, child: ChildHandleNode, proposedUpdate: Any?): Boolean {
val handle = child.childJob.invokeOnCompletion(
invokeImmediately = false,
handler = ChildCompletion(this, state, child, proposedUpdate)
)
if (handle !== NonDisposableHandle) return true // child is not complete and we've started waiting for it
val nextChild = child.nextChild() ?: return false
return tryWaitForChild(state, nextChild, proposedUpdate)
}
Возможно, полезно будет добавить или упомянуть этот момент
Вы правы, упустил момент с тем, чтобы упомянуть, что используется дефолтная тема MaterialComponents и телефон запущен в Day режиме. Добавил в статью, спасибо
Отличная статья, огромный объем работ проделан.
Но возник вопрос по этому примеру и пришлось смотреть сорсы.
В этом примере возникает вопрос, а как в итоге завершится parent coroutine, если во время ее
resumeWith
дочерние корутины еще не завершены и она завершиться не может.Как и кто в итоге вызовет ее
resumeWith
, учитывая что вы упомянули что дочерние корутины не знают про ее continuation?Ответом будет подписка на
Job
дочерних корутин, которая как раз и вызовет метод финализации стейта нашей корутины при последнемonCompletion
.При этом
resumeWith
не будет вызван повторно, но стейт корутины корректно финализируетсяВозможно, полезно будет добавить или упомянуть этот момент
Вы правы, упустил момент с тем, чтобы упомянуть, что используется дефолтная тема MaterialComponents и телефон запущен в Day режиме. Добавил в статью, спасибо