launch — الجوهر، تشغيل الكوروتينات بنمط fire-and-forget وكيف يعمل

المؤلف: IT Sectr نُشر: 2026-06-22 وقت القراءة: 7 دق

launch — منشئ Coroutine Builder في Kotlin يبدأ كوروتين دون إرجاع نتيجة، ويعيد كائن Job للتحكم في التنفيذ. ينفذ هذا المنشئ نمط fire-and-forget: يبدأ الكوروتين العمل في خلفية وينتهي تلقائياً. وفقاً لوثائق JetBrains، 2024، فإن launch هو الطريقة الأساسية لتشغيل المهام المتوازية في Kotlin Coroutines.

الخلاصة

  • launch — منشئ لبدء الكوروتينات دون إرجاع نتيجة (fire-and-forget)
  • Job — كائن للتحكم في الكوروتين بطرق cancel(), join(), isActive
  • launch يتكامل مع CoroutineScope للإلغاء التلقائي للكوروتينات التابعة
  • CoroutineStart.LAZY يسمح بتأخير التنفيذ حتى استدعاء صريح لـ start() أو join()
  • launch في Android يُستخدم لحفظ البيانات في قاعدة البيانات، واستدعاءات الشبكة، وتحديث واجهة المستخدم

ما هو launch في Kotlin Coroutines؟

launch — دالة امتداد في Kotlin، متاحة عبر استيراد kotlinx.coroutines، تنشئ كوروتين جديداً في CoroutineScope معين. على عكس الدوال العادية، الكود داخل launch يُنفذ بشكل متزامن — يمكن أن يتوقف الكوروتين دون حظر الخيط ويستأنف لاحقاً.

منشئ launch هو لبنة أساسية في نموذج الكوروتينات في Kotlin. لا يُرجع قيمة محسوبة لكنه يُرجع كائن Job يسمح بالتحكم في تنفيذ الكوروتين. جميع الكوروتينات التابعة التي تُطلق عبر launch داخل كوروتين آخر تكون مرتبطة بالأب.

صيغة وبارامترات launch

يُعرف منشئ launch كدالة inline بعدة بارامترات: CoroutineScope و CoroutineContext و CoroutineStart و suspend block. البارامترات لها قيم افتراضية، مما يجعل launch ملائماً للسيناريوهات النموذجية.

kotlin
public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job

البارامتر context يقبل CoroutineContext الذي يجمع بين dispatcher ومعالج استثناءات وعنصر مسمى. غالباً ما يتم تمرير Dispatchers.IO أو Dispatchers.Main أو SupervisorJob لعزل الأخطاء.

Job وإدارة دورة الحياة

Job — الكائن المُعاد الذي يمثل دورة حياة الكوروتين. يمكن أن يكون Job في الحالات: New, Active, Completing, Completed, Cancelling, Cancelled. تعكس كل حالة حالة التنفيذ وتسمح بالتفاعل مع التغييرات.

kotlin
val job = CoroutineScope(Dispatchers.IO).launch {
    repeat(10) { i ->
        delay(1000L)
        println("التقدم: $i")
    }
}

println("الوظيفة نشطة: ${job.isActive}")
delay(2500L)
job.cancel()
println("الوظيفة ملغاة: ${job.isCancelled}")

يدعم Job التسلسل الهرمي: إذا تم إلغاء الكوروتين الأب، يتم إلغاء جميع الكوروتينات التابعة تلقائياً. SupervisorJob يغير هذا السلوك — الكوروتينات التابعة لا تُلغى عندما يفشل أحدها.

التزامن المهيكل في launch

التزامن المهيكل يعني أن كل كوروتين يُطلق داخل CoroutineScope محدد، ولا يكتمل النطاق حتى تنهي جميع الكوروتينات التابعة عملها. launch يدعم هذا المبدأ بالكامل — الكوروتينات التي تُطلق داخل كوروتين آخر هي تابعة له.

استدعاءات launch المتداخلة

مع استدعاءات launch المتداخلة، يتشكل شجرة من الكوروتينات. ينتظر الكوروتين الأب اكتمال جميع الكوروتينات التابعة، مما يضمن ترتيب تنفيذ يمكن التنبؤ به ويبسط إدارة الموارد.

kotlin
fun main() = runBlocking {
    launch {
        launch {
            delay(1000L)
            println("اكتمل الطفل 1")
        }
        launch {
            delay(500L)
            println("اكتمل الطفل 2")
        }
        println("جميع الأطفال يكتملون قبل هذا السطر")
    }
}

يختلف هذا السلوك عن التزامن القائم على الخيوط، حيث الخيوط التابعة غير مرتبطة بالأب. في الكوروتينات، الأب لا يكتمل حتى تنهي جميع الكوروتينات التابعة عملها.

معالجة الاستثناءات في launch

معالجة الاستثناءات في launch تعتمد على نوع Job. بالنسبة لـ Job العادي، تنتشر الاستثناءات إلى الكوروتين الأب وتلغيه. بالنسبة لـ SupervisorJob أو SupervisorScope، يتم عزل الاستثناءات — خطأ في كوروتين تابع لا يؤثر على الآخرين.

kotlin
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
    try {
        riskyOperation()
    } catch (e: Exception) {
        println("تم الالتقاط: ${e.message}")
    }
}
scope.launch {
    println("هذا لا يزال يعمل بفضل SupervisorJob")
}

لمعالجة الاستثناءات غير الملتقطة بشكل عام، يُستخدم CoroutineExceptionHandler. يلتقط الاستثناءات التي لم تتم معالجتها داخل الكوروتين ويسمح بتسجيل الخطأ دون تعطل التطبيق.

أمثلة استخدام launch في Android

في Android، يُستخدم launch في كل مكان: من ViewModel إلى WorkManager. النمط الرئيسي هو استخدام lifecycleScope في Fragment و viewModelScope في ViewModel للإلغاء التلقائي للكوروتينات عند انتهاء دورة حياة المكون.

kotlin
class ProfileViewModel : ViewModel() {
    private val repository = UserRepository()

    fun loadProfile(userId: String) {
        viewModelScope.launch(Dispatchers.IO) {
            val profile = repository.fetchProfile(userId)
            withContext(Dispatchers.Main) {
                _profileState.update { it.copy(profile = profile) }
            }
        }
    }
}

viewModelScope يلغي الكوروتينات تلقائياً عند تدمير ViewModel. هذا يزيل التسريبات ويضمن أن العمليات الخلفية لا تستمر بعد فقدان السياق. بالإضافة، يمكن استخدام withContext للتبديل بين dispatchers.

الأسئلة الشائعة

ما الفرق بين launch و async في Kotlin Coroutines؟

launch يُرجع Job ولا يُرجع نتيجة، بينما async يُرجع Deferred<T> للحصول على النتيجة. يُستخدم launch للعمليات من نوع fire-and-forget، و async — عندما تحتاج لانتظار القيمة المُعادة واستخدامها.

كيف ألغي كوروتين تم تشغيله عبر launch؟

استدعِ job.cancel() على كائن Job المحفوظ. للإلغاء الجماعي، ألغِ CoroutineScope بالكامل عبر scope.cancel(). يجب أن يكون الكوروتين متعاوناً — تحقق من isActive أو استخدم دوال suspend قابلة للإلغاء.

ماذا لو ألقى launch استثناءً؟

استخدم try-catch داخل كتلة launch أو مرر CoroutineExceptionHandler في CoroutineContext. لعزل الأخطاء، استخدم SupervisorJob — عندها خطأ في كوروتين تابع لن يلغي البقية.

هل يمكن تشغيل launch بدون CoroutineScope؟

لا، launch هي دالة امتداد لـ CoroutineScope. بدون نطاق، لا يمكن للكوروتين اتباع مبدأ التزامن المهيكل. استخدم GlobalScope.launch بحذر — فهو ينشئ كوروتين بدون ارتباط بدورة الحياة.

كم عدد كوروتينات launch التي يمكن تشغيلها في وقت واحد؟

العدد محدود بمجموعة خيوط dispatcher. Dispatchers.Default يستخدم عدد خيوط يساوي عدد أنوية المعالج. Dispatchers.IO يدعم حتى 64 خيطاً. عند تشغيل عدد أكبر من الكوروتينات، يتم وضعها في طابور.

الملخص

  • launch — المنشئ الرئيسي لكوروتينات fire-and-forget، يُرجع كائن Job
  • Job يوفر طرق تحكم: cancel(), join(), isActive, isCancelled, isCompleted
  • التزامن المهيكل يضمن إلغاء الكوروتينات التابعة عند إلغاء الأب
  • معالجة الاستثناءات تعتمد على نوع Job: العادي ينشر الأخطاء، SupervisorJob يعزلها
  • lifecycleScope و viewModelScope — حلول جاهزة لتشغيل الكوروتينات في Android
  • CoroutineStart.LAZY يؤخر التنفيذ حتى استدعاء صريح لـ start() أو join()
  • launch في Android يُستخدم لطلبات الشبكة، والكتابة في قاعدة البيانات، والتحليلات، والتخزين المؤقت

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا