Я читаю «Глубокое погружение в Kotlin Coroutines» Марцина Москалы, и у меня проблема с пониманием функции suspendCoroutine.
AFAIK, suspendCoroutine — это низкоуровневый API, который помогает вам владеть объектом продолжения до приостановки работы сопрограммы и выполнять с ним какие-либо действия.
Как утверждает Марчин Москала,
он заканчивается лямбда-выражением ({ }). Функция передается как аргумент будет вызван перед приостановкой. Эта функция получает продолжение как аргумент. Функция suspendCoroutine позволяет использовать продолжение непосредственно перед приостановкой. После suspendCoroutine позвони, будет поздно.
Итак, что здесь на самом деле происходит? У меня есть следующие вопросы:
Я знаю этот ответ, но до сих пор не понимаю
Я также знаю, что технически этот объект продолжения может быть сохранен, сопрограмма действительно приостанавливается, и позже мы можем вызвать .resume для сохраненного объекта в каком-то другом потоке управления, но этот сценарий, похоже, является неправильным использованием API сопрограмм из-за утечек памяти.
Это просто оболочка для обратных вызовов, чтобы избежать ада обратных вызовов?
Пожалуйста, разъясните идею использования suspendCoroutine.





suspendCoroutine используется для соединения других асинхронных моделей, таких как обратные вызовы, фьючерсы и т. д., с сопрограммами. Он «преобразовывает» существующий асинхронный код в режим приостановки.
В целом схема использования такая:
resume, чтобы возобновить работу сопрограммы. Как/где/когда мы вызываем resume во многом зависит от типа асинхронной операции и ее API.Прямо отвечая на ваши вопросы:
Ад.1. Если мы поместим resume прямо в лямбду (что в некоторых случаях может иметь смысл), я подозреваю, что она даже не приостановится. Но он также может приостановить и немедленно возобновить работу. Я думаю, что эта функция не гарантирует ни одного из этих вариантов поведения.
Ад.2. Если мы поместим синхронный блокирующий код непосредственно в лямбду, это означает, что мы заблокировали сопрограмму аналогично тому, как если бы мы вообще не использовали suspendCoroutine. Это неправильный способ использования suspendCoroutine. Обычно ожидается, что лямбда, передаваемая suspendCoroutine, только планирует асинхронную операцию и завершается почти сразу.
Я также знаю, что технически этот объект продолжения может быть сохранен, сопрограмма действительно приостанавливается, и позже мы можем вызвать .resume для сохраненного объекта в каком-то другом потоке управления, но этот сценарий, похоже, является неправильным использованием API сопрограмм из-за утечек памяти.
Это просто оболочка для обратных вызовов, чтобы избежать ада обратных вызовов?
Это не неправильное использование API сопрограмм, это именно то, как мы должны использовать suspendCoroutine. Это не вызывает каких-либо утечек памяти, если предположить, что исходный код, основанный на обратных вызовах, не вызывал их.