Приведённый suspendCoroutine превращает одноразовый callback в приостанавливаемое ожидание, а не в блокировку потока. Для отменяемого сетевого запроса предпочтительнее suspendCancellableCoroutine.
Преобразование функции с callback в suspend‑функцию
Приведённый suspendCoroutine превращает одноразовый callback в приостанавливаемое ожидание, а не в блокировку потока. Для отменяемого сетевого запроса предпочтительнее suspendCancellableCoroutine.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В проекте используется API, которое осуществляет сетевой запрос. Его метод getUser принимает идентификатор и функцию‑обработчик (callback). Требуется обернуть этот асинхронный вызов в suspend‑функцию, чтобы можно было получать результат в корутине без явного колбэка.
//--> метод getUser работает асинхронно но нам нужно получить данные синхронно в корутине
Api().getUser(id) { user ->
}
//ответ
suspend fun getUser(id: String): User = suspendCoroutine<User> { continuation ->
Api().getUser(id) { user ->
continuation.resume(user)
}
}
Ответ
Приведённый suspendCoroutine превращает одноразовый callback в приостанавливаемое ожидание, а не в блокировку потока. Для отменяемого сетевого запроса предпочтительнее suspendCancellableCoroutine.
Оригинальная обёртка корректна, если callback вызывается ровно один раз и API действительно всегда завершает его. Если есть callback ошибки, он должен вызвать resumeWithException. Для отменяемого API сохраните handle запроса и зарегистрируйте invokeOnCancellation { handle.cancel() }. Если исходный API не поддерживает отмену, обёртка не может магически остановить сеть. Важно также защититься от повторного callback по контракту источника.
Источник: kotlinlang.org.