Ответ
Для трансформации suspend-функций в Java-совместимый код (например, для использования в RxJava или колбэках) используют класс Continuation. Kotlin компилятор автоматически преобразует suspend-функции в конечный автомат с Continuation, который управляет приостановкой и возобновлением корутин.
Пример с suspendCoroutine для ручного управления:
suspend fun fetchData(): String = suspendCoroutine { continuation ->
someAsyncApi.call(object : Callback {
override fun onSuccess(result: String) {
continuation.resume(result)
}
override fun onError(error: Throwable) {
continuation.resumeWithException(error)
}
})
}
Здесь continuation позволяет возобновить выполнение корутины после асинхронного вызова.
Ответ 18+ 🔞
Ёпта, ну слушай, тут такая тема интересная. Когда тебе надо из этих твоих приостановленных функций на Kotlin сделать что-то, что поймут в старом добром Java-мире — там, где правят бал RxJava или эти вездесущие колбэки — то тут на сцену выходит, блядь, класс Continuation.
Представляешь, компилятор Kotlin'а берёт твою suspend-функцию и делает с ней такую магию, что она превращается в этакий конечный автомат. А этот самый Continuation — он как дирижёр в этом оркестре, он управляет всей этой хуйней: где корутину приостановить, а где — ёпта — возобновить. Удивление пиздец, правда?
Ну а если ты хочешь сам всё пощупать и покрутить, то есть такой приём — suspendCoroutine. Это когда ты вручную, как заправский механик, управляешь этим процессом. Смотри, как это выглядит:
suspend fun fetchData(): String = suspendCoroutine { continuation ->
someAsyncApi.call(object : Callback {
override fun onSuccess(result: String) {
continuation.resume(result) // Всё, приехали, возобновляемся с результатом
}
override fun onError(error: Throwable) {
continuation.resumeWithException(error) // А тут, бля, с ошибкой
}
})
}
Вот видишь? Ты создаёшь этот самый continuation и держишь его, как козырь в рукаве. Пока твой какой-то левый асинхронный API там что-то делает, корутина висит, не дёргается. А как только приходит ответ — успешный или не очень — ты просто тычешь в континуэйшен: «На, братан, вот результат, давай дальше работай» или «Вот, слови исключение, разбирайся». И всё, машина снова запускается. Гениально и просто, как угол дома. Главное — не перепутать, где resume, а где resumeWithException, а то будет тебе хиросима, а не работающий код.