Комментарии 20
Спасибо, приятно было читать.
Спасибо за статью. Очень полезная информация.
Вот еще хорошая статья на эту тему:
https://victorbrandalise.com/coroutines-part-ii-job-supervisorjob-launch-and-async/
Спасибо за такую отличную статью!
Спасибо за статью, очень интересный материал
Глядя на всё это рождается вопрос - а нафига они нужны и в чем отличие от базовой работы с потоками? Код проще-то не выглядит.
Проще выглядит.
Долгие операции не стопают поток. Например, пока СУБД думает, как ответить на рекурсивный селект с тремя юнионами и десятью джойнами в наш поток внедряется что-то легковесное типа гет одной записи из репозитория, второй клиент забирает свой ответ и радостный (200) уходит, потом база выплевывает что-то, и отдаем это первому клиенту, если он не устал еще (TIMEOUT). Второму клиенту не нужно ждать в очереди. А еще и третий и четвертый могут успеть.
И код всё-таки проще.
Плюс еще для android google продвигает корутины как рекомендуемый подход для асинхронной работы и рынок чаще выбирает корутины, т.к. больше людей при изучении android учат корутины чем rxJava и нативные JVM потоки.
Как пример https://pl.kotl.in/Ha6iriRGk
Так вы описали работу пула потоков с задачами.
Да, но в нативных потоках задачи берут себе полностью забирают поток на время исполнения, а в корутинах пока задаче поток не нужен, поток будет выполнять другую задачу.
В примере который я скинул можно заменить newSingleThreadExecutor на newCachedThreadPool и он отработает примерно за тоже время что и корутины, но тогда в пуле будет создано 3 потока, когда корутинам будет достаточно одного
Да, а еще jvm-ный пул потоков превратить в корутинный диспатчер- вот тогда магия и начнется.
Долго исполняющийся код сможет вернуться не в свой поток, если тот занят, а в освободившийся, и отработает максимально быстро по сравнению с голым тред пулом.
Если я правильно понял под взаимовлиянием имеется в виду что одна корутина может быть родителем другой. А какая логика происходит если дочерняя или родительская корутина бросила исключение как раз описана в текущей статье.
Спасибо за статью. Сложная тема, легко себе в ногу стрельнуть. Поэтому в своем коде стараюсь вообще не выкидывать и не ловить исключения. Использую kotlin.Result как альтернативу.
Статья хорошая, но каждый раз читая очередную статью о том, как же "просто" в корутинах устроена обработка ошибок, задумываюсь если все так просто, то зачем 100500 статей об этом?
Сам по этим граблям ходил, иногда выбешивает нереально.
У меня была такая же ситуация, поэтому и появилась эта статья)
В ней я пытался донести что на самом деле обработка ошибок не сложная, а умещается в одно правило по отношению к корутинам «СРАЗУ распространяют ошибку. ЕСЛИ ее не может обработать родитель, делают это сами».
Самому когда раньше читал статьи на эту тему не хватало общего правила, т.к. чаще всего дело ограничивалось частными примерами без выявления общего правила.
Меня в этой ситуации больше всего удручает поведение async от него все же хочется, обработки ошибок в момент получения результата.
Если имеется в виду поведение которое описано в Мифе 2, то тут как бы дается гибкость и вариативность поведения.
Иногда может нужно отменить скоуп не дожидаясь await. Например мы в async идет в базу получить строку что бы найти ее в файлах на диске. Т.е. в начале мы делаем async, потом читает 10 файлов, а потом через await берем строку и ищем ее в файлах. В этом случае если это все сделаем в coroutineScope, то он перестанет читать как только async завершится с исключением.
Пример придуманный, но наверно если какие то похожие случаи которые в реальной жизни есть.
Как я перестал волноваться и полюбил ошибки в Kotlin корутинах: Мифы обработки ошибок в корутинах