Отличная статья, огромный объем работ проделан. Но возник вопрос по этому примеру и пришлось смотреть сорсы.
/*
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 режиме. Добавил в статью, спасибо