تخطَّ إلى المحتوى

suspend / launch / async

الكوروتينات suspend / launch / async

الكوروتينات طريقة Kotlin الخفيفة للبرمجة غير المتزامنة بكود يبدو متسلسلًا بدل تعقيد الخيوط والـ callbacks.

دالة suspend يمكن إيقافها واستئنافها دون حجز الخيط (thread) الذي تعمل عليه — بخلاف Thread.sleep الذي يحجزه فعليًّا. launch تبدأ كوروتين في الخلفية دون انتظار نتيجة (fire-and-forget). async تبدأ كوروتين يُرجع نتيجة عبر Deferred، تُستخرج لاحقًا بـ await(). كلاهما يحتاج نطاق تنفيذ (CoroutineScope) مثل runBlocking أو viewModelScope في أندرويد.

الصياغة

suspend fun الاسم(...): نوع { ... }
launch { /* بلا نتيجة */ }
val d = async { /* يُرجع نتيجة */ }
d.await()

📄 مثال

import kotlinx.coroutines.*

suspend fun fetchUser(id: Int): String {
    delay(500)              // انتظار غير محظور للخيط
    return "مستخدم #$id"
}

fun main() = runBlocking {
    launch { println(fetchUser(1)) }   // خلفية، بلا انتظار نتيجة هنا

    val a = async { fetchUser(2) }
    val b = async { fetchUser(3) }
    println("${a.await()} و ${b.await()}")  // ينفّذان بالتوازي
}

أهم النقاط

العنصرالوظيفة
suspend funدالة قابلة للإيقاف دون حجز الخيط، تُستدعى من كوروتين أو دالة suspend أخرى
delay()انتظار غير محظور — بديل Thread.sleep داخل دوال suspend
launch { }يبدأ كوروتين بلا نتيجة مُرجَعة
async { }يبدأ كوروتين يُرجع Deferred؛ نتيجته تُستخرج عبر await()

💡 نصائح عملية

  • استخدم async فقط عند الحاجة لنتيجة متوازية من عدة عمليات؛ launch كافية للمهام الجانبية
  • في أندرويد، استخدم النطاق المناسب (viewModelScope/lifecycleScope) بدل GlobalScope لتفادي تسريب الذاكرة

⚠️ أخطاء شائعة

  • استدعاء دالة suspend مباشرة من دالة عادية (غير suspend) خارج نطاق كوروتين — خطأ ترجمة
  • استخدام Thread.sleep داخل كوروتين بدل delay — يحجز الخيط فعليًّا ويلغي فائدة الكوروتينات

خصائص ذات صلة

🎓 تريد فهم الصورة الكاملة خطوة بخطوة؟ ابدأ من مسار KOTLIN الكامل بالعربي.