Этот вопрос проверяет понимание, как suspendCancellableCoroutine преобразует асинхронные колбэки в последовательный suspend-код.
suspendCancellableCoroutine приостанавливает корутину и предоставляет Continuation, который можно возобновить вручную. Это позволяет обернуть API с колбэками в suspend-функцию, делая код линейным. Если корутина отменяется, можно корректно освободить ресурсы.
Многие асинхронные библиотеки (например, Retrofit, Firebase) используют колбэки, но в корутинах удобнее работать с suspend-функциями. suspendCancellableCoroutine помогает преобразовать колбэк в последовательный код.
Пример: обёртка для callback-based API
suspend fun fetchData(): String = suspendCancellableCoroutine { continuation ->
someApi.call(object : Callback {
override fun onSuccess(result: String) {
continuation.resume(result) // Возобновляем корутину с результатом
}
override fun onFailure(error: Throwable) {
continuation.resumeWithException(error) // Пробрасываем ошибку
}
})
// Если корутина отменена, отменяем вызов API
continuation.invokeOnCancellation {
someApi.cancel()
}
}Как это работает:
Корутина приостанавливается при вызове suspendCancellableCoroutine.
Мы получаем continuation, который можно возобновить (resume) или завершить с ошибкой (resumeWithException).
Если корутина отменяется, срабатывает invokeOnCancellation, где можно отменить операцию.
Преимущества:
Код выглядит как последовательный, без вложенных колбэков.
Поддержка отмены корутин.
Интеграция с существующими API.
Вывод:suspendCancellableCoroutine — это мост между старыми колбэк-API и современными корутинами, делая асинхронный код чище и управляемее.