Поведение исключений в разных типах корутин

В исходном виде код не компилируется: async возвращает Deferred<Int>, а не Int; async и launch также требуют CoroutineScope. Поведение ошибок зависит от родительской области.

Короткий ответ

Что ответить на собеседовании

В исходном виде код не компилируется: async возвращает Deferred<Int>, а не Int; async и launch также требуют CoroutineScope. Поведение ошибок зависит от родительской области.

Подробный разбор

Ответ с пояснениями

Условие

Нужно понять, как будет реагировать программа при вызове функций someFun и someFun2.

fun someFun() {
    val a: Int = async { suspendFun() }
    someFun1111()
}

fun someFun2() {
    launch { suspendFun() }
    someFun2323()
}

fun suspendFun(): Int {
    throw RuntimeException()
}

Ответ

В исходном виде код не компилируется: async возвращает Deferred<Int>, а не Int; async и launch также требуют CoroutineScope. Поведение ошибок зависит от родительской области.

После исправления типов async позволяет получить результат через await(), а launch возвращает Job. Но неверно говорить, что ошибка дочернего async всегда скрыта до await: в обычной структурированной области она также отменяет родителя.

someFun1111() и someFun2323() стоят после запуска, а не после ожидания, поэтому не гарантируется, что они выполнятся после завершения дочерней операции. Если нужна такая последовательность, используйте await для результата или join для завершения.

В примере suspendFun фактически обычная функция, несмотря на название. Её RuntimeException возникает сразу при вызове. Для полноценного ответа сначала следует определить scope, отношение parent/child и способ обработки ошибки; без этого единственного сценария выполнения нет.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее