Suspend function — bu suspend modifikatoriga ega bo'lgan, oqimni bloklamasdan bajarilishini to'xtatib, keyinroq xuddi shu korutinda davom ettirishi mumkin bo'lgan funksiyadir. JetBrains Kotlin Docs, 2025 ma'lumotlariga ko'ra, suspend funksiyalari korutinlarning asosiy qurilish blokidir, callback-larsiz asinxronlikni ta'minlaydi. Har bir suspend funksiyasi Continuation asosidagi state-mashinasiga kompilyatsiya qilinadi, bu to'xtash nuqtalarini samarali boshqarish imkonini beradi.
Asosiy fikrlar
Suspend function — bu suspend kalit so'zi bilan e'lon qilingan, oqimni bloklamasdan bir yoki bir nechta nuqtada bajarilishini to'xtata oladigan funksiyadir. Boshqa suspend funksiyasi ichidagi har bir suspend funksiyasi chaqiruvi potentsial to'xtash nuqtasidir.
suspend fun fetchUserData(): User {
val response = httpClient.get("/user")
return parser.parse(response)
}
Kotlin kompilyatori bunday funksiyani state-mashinasiga o'zgartiradi. Har bir to'xtash nuqtasi (boshqa suspend funksiyasining chaqiruvi) state (label) ga aylanadi. Joriy oqim state-lar orasida bo'shatiladi va kutilayotgan operatsiya tugagandan so'ng, bajarilish keyingi state dan davom etadi.
Suspend funksiyalari Kotlin 1.3 da (2018 yil) korutinlar bilan birga eksperimental xususiyat sifatida paydo bo'ldi va Kotlin 1.5 da (2021 yil) barqarorlashdi. Bungacha Kotlin/Java da asinxronlik callback-lar, RxJava va CompletableFuture orqali ta'minlanardi. Suspend funksiyalari chiziqli sintaksis va avtomatik oqim boshqaruvi bilan muqobil taklif qildi.
Suspend funksiyalarining ichki tuzilishini tushunish korutinlar bilan to'g'ri ishlashning kalitidir. Oddiy funksiyalardan farqli o'laroq, har bir suspend funksiyasi Continuation interfeysiga ega sinfga kompilyatsiya qilinadi.
Kotlin kompilyatori suspend funksiyasining har bir parametri oxiriga Continuation turidagi parametr qo'shadi. Continuation quyidagilarni o'z ichiga oladi:
Faraz qilaylik, boshqa suspend funksiyalariga ikkita chaqiruvga ega suspend funksiyamiz bor:
suspend fun process() {
val a = stepOne()
val b = stepTwo(a)
println(b)
}
Kompilyator uni belgilar bilan state-mashinasiga o'zgartiradi:
// Yaratilgan kodning soddalashtirilgan ko'rinishi
fun process(cont: Continuation<Unit>): Any? {
val cont = cont as ProcessContinuation
when (cont.label) {
0 -> {
cont.label = 1
if (stepOne(cont) == COROUTINE_SUSPENDED) return COROUTINE_SUSPENDED
}
1 -> {
cont.label = 2
val a = cont.result as TypeA
if (stepTwo(a, cont) == COROUTINE_SUSPENDED) return COROUTINE_SUSPENDED
}
2 -> {
println(cont.result)
Unit
}
}
}
Asosiy kuzatish: agar funksiya COROUTINE_SUSPENDED qaytarsa, joriy oqim bo'shatiladi. Asinxron operatsiya tugagach, Continuation.resumeWith chaqiriladi va state-mashinasi keyingi label dan davom etadi.
Suspend funksiyasining e'loni oddiy funksiyadan farq qilmaydi, faqat fun dan oldin suspend kalit so'zi qo'shiladi. Faqat bitta cheklov bor: suspend funksiyasini faqat korutindan yoki boshqa suspend funksiyasidan chaqirish mumkin.
suspend fun delayAndReturn(ms: Long): String {
delay(ms)
return "Done after ${ms}ms"
}
Ushbu misolda delay ham suspend funksiyasidir, u korutinani oqimni bloklamadan belgilangan millisekundga to'xtatadi. Kechikishdan so'ng bajarilish tiklanadi.
fun main() = runBlocking {
val result = delayAndReturn(1000)
println(result)
}
runBlocking oddiy dunyo bilan korutinlar o'rtasida ko'prik yaratadi. Lambda ichida istalgan suspend funksiyasini chaqirish mumkin.
Kotlin funksional turlarning suspend versiyalarini qo'llab-quvvatlaydi — suspend () -> T va suspend (A) -> B. Bu asinxron lambdalarni yuqori darajali funksiyalarga uzatish imkonini beradi:
suspend fun withRetry (
retries: Int = 3,
block: suspend () -> T
): T {
repeat(retries - 1) {
try { return block() }
catch (_: Exception) { delay(100) }
}
return block()
}
withRetry funksiyasi suspend lambda qabul qiladi va xatolarda uni qayta bajaradi. Bu qayta urinishlar bilan tarmoq so'rovlari uchun odatiy naqshdir.
Suspend va oddiy funksiyalar o'rtasidagi farqlar oddiy modifikator qo'shishdan tashqariga chiqadi. Keling, asosiy farqlarni ko'rib chiqaylik.
| Xususiyat | Oddiy funksiya | Suspend funksiyasi |
|---|---|---|
| Bajarilish oqimi | Oqimni tugaguncha bloklaydi | Oqimni bo'shatib, keyin davom ettirishi mumkin |
| Kompilyator parametrlari | Faqat ko'rsatilgan parametrlar | Oxirida yashirin Continuation |
| Oddiy funksiyadan chaqirish | Ha | Yo'q |
| Stack | Oqimning fizik stacki | Heap da state-mashinasi + nuqtalar orasida fizik stack |
| Qaytarish | To'g'ridan-to'g'ri qiymat | Qiymat yoki COROUTINE_SUSPENDED |
| Ish unumdorligi | Minimal qo'shimcha yuk | ~state-mashinasi uchun bir necha nanosekund (Kotlin 1.9+) |
Oddiy funksiyada Continuation yo'q — holatni saqlash va bajarilishni tiklash uchun joyi yo'q. Agar oddiy funksiyadan suspend funksiyasini chaqirish kerak bo'lsa, runBlocking (testlar uchun) yoki CoroutineScope.launch (ishlab chiqarish uchun lifecycle ni hisobga olgan holda) dan foydalaning.
Kotlin da Android ilovalarida suspend funksiyalaridan foydalanishning uchta real stsenariysini ko'rib chiqaylik.
Room suspend funksiyalarini bevosita qo'llab-quvvatlaydi — so'rov avtomatik ravishda fon oqimida bajariladi:
@Dao
interface UserDao {
@Query("SELECT * FROM users WHERE id = :id")
suspend fun getUser(id: Int): User?
@Insert
suspend fun insertUser(user: User)
}
Room ichki ravishda so'rovni bajarish uchun Dispatchers.IO dan foydalanadi va natija suspend funksiyasi chaqirilgan dispetcherga qaytariladi.
class ProfileViewModel : ViewModel() {
private val repo = ProfileRepository()
fun loadProfile(id: String) {
viewModelScope.launch {
val profile = repo.getProfile(id)
_profile.value = profile
}
}
}
ViewModelScope.launch korutin yaratadi, uning ichida getProfile suspend funksiyasi chaqiriladi. Natija olingandan so'ng UI asosiy oqimda yangilanadi.
suspend fun placeOrder(cart: Cart): OrderResult {
val validated = validateCart(cart)
val payment = processPayment(validated)
val receipt = sendReceipt(payment)
return receipt
}
Uchta suspend funksiyasi ketma-ket bajariladi. Har bir qadamda korutina oqimni bloklamasdan to'xtashi mumkin. Agar biror qadam istisno tashlasa — qolganlari bajarilmaydi, bu buyurtmaning noto'g'ri holatlaridan himoya qiladi.
Hatto tajribali Kotlin dasturchilari ham suspend funksiyalarini loyihalashda xato qiladilar. Eng keng tarqalganlarini ko'rib chiqaylik.
Suspend funksiyasi kodni avtomatik ravishda asinxron qilmaydi. Thread.sleep(), InputStream.read() va boshqa bloklovchi chaqiruvlar baribir oqimni bloklaydi. Bloklovchi operatsiyalarni o'rash uchun withContext(Dispatchers.IO) dan foydalaning.
Agar funksiya boshqa suspend funksiyalarini chaqirmasa va asinxron operatsiyalarni bajarmasa — suspend modifikatori ortiqcha. State-mashinasiga qo'shimcha yuk qo'shadi va chaqiruv kontekstini cheklaydi. Funksiyani faqat haqiqatan to'xtaganda suspend qiling.
Korutin bekor qilinganda, suspend funksiyalari CancellationException tashlaydi. Uni o'ylamasdan tutmang — chaqiruvchi kodni bekor qilishni to'g'ri yakunlash imkoniyatidan mahrum qilasiz. Agar yakunlovchi operatsiyani bajarish kerak bo'lsa, finally bloki va NonCancellable dan foydalaning.
suspend fun safeOperation() {
try {
doWork()
} finally {
withContext(NonCancellable) {
cleanup()
}
}
}
finally bloki har doim bajariladi, bekor qilishni ham o'z ichiga oladi, NonCancellable esa tozalashning uzilmasligini kafolatlaydi.
Korutin yaratmasdan callback dan to'g'ridan-to'g'ri suspend funksiyasini chaqirib bo'lmaydi. Callback uslubini korutinlarga moslashtirish uchun suspendCoroutine yoki suspendCancellableCoroutine dan foydalaning.
Tez-tez so'raladigan savollar
Ha, texnik jihatdan suspend funksiyasi boshqa suspend funksiyalarini chaqirmasligi mumkin. Kompilyator bitta state-li (label 0) state-mashinasini yaratadi. Biroq, bunday funksiyaning amaliy foydasi yo'q — u oddiy funksiya kabi bajariladi, lekin qo'shimcha yuk bilan. Keraksiz suspend dan foydalanmang.
Kotlin kotlinx-coroutines-debug kutubxonasini taqdim etadi — DebugProbes va korutin kuzatish vositalari bilan. Arctic Fox versiyasidan boshlab Android Studio da Debugger da Coroutines yorlig'i mavjud bo'lib, u aktiv korutinlar, ularning holati va to'xtash nuqtalarini ko'rsatadi.
Har bir to'xtash nuqtasi state-mashinasida yangi state yaratadi. Aksariyat ilovalar uchun bitta nuqtaning qo'shimcha yuki nanosekundlarni tashkil qiladi (Kotlin 1.9+). Faqat sikl ichida o'n minglab nuqtalar bo'lganda operatsiyalarni birlashtirish yoki sequence/flow dan foydalanish tavsiya etiladi.
Kotlin da suspend funksiya turining modifikatoridir, qaytariladigan qiymatning belgisi emas (C# da async kabi). Istalgan suspend funksiyasi istalgan parametr va qaytarish turiga ega bo'lishi mumkin va uning chaqiruvi sintaktik jihatdan oddiy funksiya chaqiruvidan farq qilmaydi — chaqiruv joyida await operatori mavjud emas.
Moslashtirish uchun suspendCancellableCoroutine dan foydalaning. Ichkarida continuation.resume() ni chaqiradigan callback ro'yxatdan o'tkazishni uzatasiz va agar callback obunani bekor qilishni qo'llab-quvvatlasa, bekor qilish tokenini qaytarasiz. Bu eski Android API larini o'rash uchun standart naqshdir.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.