Чем suspend-функция отличается от обычной?

suspend-функция в Kotlin — это функция, которая может быть приостановлена и возобновлена без блокировки потока. Это ключевая часть корутинной модели асинхронного программирования. Она отличается от обычной функции тем, как она выполняется и где может вызываться.

🔹 Основные отличия между обычной и suspend-функцией

Критерий Обычная функция suspend-функция
Вызов Можно вызывать откуда угодно Можно вызывать только из другой suspend-функции или корутины
--- --- ---
Асинхронность Выполняется синхронно, блокируя поток Может приостанавливать выполнение, не блокируя поток
--- --- ---
Поток Блокирует поток при долгой работе Не блокирует поток (например, при delay)
--- --- ---
Компилятор Компилируется как обычная функция Компилируется в машинный код с callback-механизмом
--- --- ---
Поддержка в корутинах ❌ Нет ✅ Да, основа корутин
--- --- ---

Пример обычной функции

fun fetchData(): String {
Thread.sleep(1000) // блокирует поток
return "result"
}

→ Эта функция блокирует поток, в том числе UI-поток, если вызвать её из него — приложение «подвиснет».

🔧 Пример suspend-функции

suspend fun fetchData(): String {
delay(1000) // не блокирует поток
return "result"
}

→ delay() приостанавливает выполнение только этой корутины, а не потока, на котором она работает.

📌 Где можно вызвать suspend-функцию

  • Внутри другой suspend-функции.

  • Внутри корутины (launch, async).

  • В runBlocking (например, в тестах или main()).

Пример:

fun main() = runBlocking {
val result = fetchData() // вызов suspend-функции
println(result)
}

⚠️ Важно:

suspend-функции не запускаются в отдельном потоке автоматически — они просто могут быть приостановлены. Чтобы реально выполнять их в фоновом потоке, нужно использовать withContext(Dispatchers.IO) или запускать в Dispatchers.Default, IO, и т. д.

suspend fun loadData(): String = withContext(Dispatchers.IO) {
// фоновая работа
"Data from disk"
}

🧠 Почему suspend — это не про потоки

Многие думают, что suspend-функции — это "потоки", но на самом деле:

  • suspend-функция — это точка, где выполнение может быть приостановлено, и позже продолжено.

  • При этом поток не занят во время паузы — он свободен выполнять другие задачи.

💡 Для чего использовать suspend-функции

  • Сетевые запросы (Retrofit, ktor)

  • Чтение/запись в базу данных (Room)

  • Задержки (delay)

  • Операции с файлами

  • Всё, что требует асинхронности **без блокировки UI
    **

Итого

Обычная функция suspend-функция
Выполняется последовательно Может приостанавливаться и возобновляться
--- ---
Блокирует поток Не блокирует поток
--- ---
Используется в любом коде Только в suspend-контексте
--- ---
Не требует корутин Требует вызова из корутины или другой suspend-функции
--- ---

suspend делает код асинхронным без потерь читаемости, сохраняя линейный стиль вместо вложенных колбэков и сложной логики управления потоками.