launch стартует Job «fire-and-forget» (исключения через handler/родителя); async возвращает Deferred с результатом, ошибка всплывает на await().
Разбор
launch — побочные эффекты; async — параллельный расчёт значения.
- Не используйте
async без await (потеря ошибок).
- Параллель:
coroutineScope { val a = async {}; val b = async {}; a.await() to b.await() }.
awaitAll для списков Deferred.
Итог
launch = эффект; async = значение (обязательно await).