Разве «Global.async{}» не делает то же самое, что и «Global.launch{}», и даже больше? Если да, то зачем придумали Global.launch{}? пожалуйста, предоставьте твердую ситуацию, если это возможно.
Я уже много искал, но не нашел убедительного ответа.
Чтобы устранить очевидную разницу: async
сопрограммы могут возвращать значение, тогда как launch
сопрограммы не могут. Я думаю, вы знаете это и спрашиваете, делает ли launch
что-то, что нельзя сделать с помощью async
сопрограммы, которая возвращает Unit
.
Основное различие между async
и launch
заключается в том, как они обрабатывают ошибки при запуске в качестве корневых сопрограмм. Корневая сопрограмма — это сопрограмма, которая запускается непосредственно в корневой области, а не как дочерняя часть существующей сопрограммы.
Когда вы создаете корневую сопрограмму с помощью launch
, исключения распространяются на область действия UncaughtExceptionHandler
, если она есть. Это связано с тем, что в противном случае ошибка была бы потеряна. Задание не возвращает результат, поэтому в коде больше нет места, где можно было бы обработать ошибку.
Однако, когда вы создаете корневую сопрограмму с помощью async
, исключения перехватываются и содержатся в результирующем объекте Deferred
. Исключение выдается, когда вы вызываете await
. Он не распространяется на UncaughtExceptionHandler
. Это потому, что мы ожидаем, что какой-то другой код в конечном итоге await
выдаст результат задания и обработает ошибку.
Это различие применяется только к корневым сопрограммам. Когда вы запускаете сопрограмму как дочернюю для существующей сопрограммы, ошибки всегда распространяются на родительское задание, независимо от того, была ли сопрограмма запущена с помощью async
или launch
.
Итак, чтобы ответить на ваш вопрос, launch
предоставляет дополнительную возможность обрабатывать ошибки с помощью UncaughtExceptionHandler
при запуске корневых сопрограмм.
Спасибо Сэм, ты прояснил это больше для меня. Я прочитал ответ по этой ссылке stackoverflow.com/questions/46226518/… как указали Alex.T и Джефф Боуман, и я нашел его очень полезным, но вы уточнили его больше. Спасибо.
Стоит отметить, что ответ Романа на связанный вопрос устарел благодаря введению (им, по иронии судьбы) структурированного параллелизма. В своем ответе он говорит, что неперехваченное исключение внутри async
сопрограммы всегда отбрасывается, если вы его await
не используете. На самом деле, это уже не так для сопрограмм, запущенных как дочерний элемент существующей сопрограммы. В этом случае неудачное задание async
по-прежнему приведет к сбою родительского задания. Однако исходный ответ Романа по-прежнему верен для корневых сопрограмм.
Отвечает ли это на ваш вопрос? В чем разница между запуском/присоединением и асинхронным/ожиданием в сопрограммах Kotlin