
Coroutines هي ميزات رائعة متوفرة في لغة Kotlin. لقد جربته بالفعل وأعجبني حقًا.
الغرض من هذه المقالة هو مساعدتك على فهم Corutins. فقط كن حذرا عند القراءة وسوف تنجح.
لنبدأ بالتعريف الرسمي لكوروتين.
Coroutines هي طريقة جديدة لكتابة التعليمات البرمجية غير المتزامنة وغير المحظورة.
السؤال الأول الذي يطرح عند قراءة هذا التعريف هو كيف تختلف Coroutines عن التدفقات؟
Coroutines هي تدفقات خفيفة الوزن. الخيط خفيف الوزن يعني أنه غير مرتبط بالخيط الأصلي ، وبالتالي لا يتطلب تبديل السياق إلى المعالج ، وبالتالي فهو أسرع.
ماذا يعني "عدم إرفاق الموضوع الأصلي" ؟
تم العثور على Coroutines في العديد من لغات البرمجة.
بشكل أساسي ، هناك نوعان من Corutin:
- باستخدام المكدس ؛
- مكدس عدم الاستخدام ؛
يقوم Kotlin بتنفيذ Coroutines بدون مكدس - وهذا يعني أن Coroutines ليس لديها مكدس خاص بها ، لذلك فهي غير مرتبطة بالخيط الأصلي.
كل من Coroutines وتيارات تعدد المهام. لكن الفرق هو أن الخيوط يتم التحكم فيها بواسطة نظام التشغيل ، و Coroutines بواسطة المستخدمين.
الآن يمكنك قراءة وفهم مقتطفات من موقع Kotlin الرسمي بوعي:
يمكن تمثيل Coroutines في شكل تدفق سهل. مثل الخيوط ، يمكن أن تعمل coroutines بالتوازي ، وتنتظر بعضها البعض وتتواصل. الاختلاف الأكبر هو أن coroutines رخيصة للغاية ، تقريبًا مجانية: يمكننا إنشاؤها بالآلاف ودفع القليل جدًا من حيث الأداء. تيارات باهظة الثمن. يمكن أن يكون ألف خيط مشكلة خطيرة حتى بالنسبة للآلة الحديثة.
دعونا نرى كيفية العمل مع Coroutines
لذا ، كيف تبدأ coroutine (على غرار بدء خيط)؟
هناك وظيفتان لإطلاق coroutines:
إطلاق {} vs async {} في Kotlin Coroutines
الفرق هو أن launch{}
لا يُرجع شيئًا ، ويعيد async{}
future.get()
يحتوي على وظيفة await()
تُرجع نتيجة كوروتين ، تمامًا مثل Future
in Java ، حيث نقوم future.get()
للحصول على النتيجة .
دعنا نلقي نظرة على استخدام الإطلاق {}
fun main(args: Array<String>) { println("Kotlin Start") launch(CommonPool) { delay(2000) println("Kotlin Inside") } println("Kotlin End") }
// The output will be // Kotlin Start // Kotlin End // Kotlin Inside
سيقوم هذا الرمز بتشغيل Coroutine جديد في تجمع مؤشرات الترابط هذا. في هذه الحالة ، نستخدم CommonPool ، التي تستخدم ForkJoinPool.commonPool () . لا تزال التدفقات موجودة في برنامج قائم على coroutine ، ولكن يمكن لمؤشر ترابط واحد تشغيل الكثير من coroutines ، لذلك ليست هناك حاجة لكثير من الخيوط.
لنجرب شيئًا واحدًا:
fun main(args: Array<String>) { delay(2000) }
إذا قمت بذلك مباشرة في الوظيفة الرئيسية ، ستتلقى رسالة خطأ:
يمكن استدعاء وظائف المقاطعة فقط من coroutine أو وظيفة مقاطعة أخرى.
إن وظيفة التأخير هي وظيفة مقاطعة ، لذا لا يمكننا استدعاؤها إلا من وظيفة مقاطعة أو وظيفة مقاطعة أخرى.
لنصلح هذا:
fun main(args: Array<String>) { runBlocking { delay(2000) } }
مثال آخر:
suspend fun doWorkFor1Seconds(): String { delay(1000) return "doWorkFor1Seconds" }
suspend fun doWorkFor2Seconds(): String { delay(2000) return "doWorkFor2Seconds" }
// Serial execution private fun doWorksInSeries() { launch(CommonPool) { val one = doWorkFor1Seconds() val two = doWorkFor2Seconds() println("Kotlin One : " + one) println("Kotlin Two : " + two) } }
// The output is // Kotlin One : doWorkFor1Seconds // Kotlin Two : doWorkFor2Seconds
الآن دعونا نلقي نظرة على استخدام المتزامن {}
// Parallel execution private fun doWorksInParallel() { val one = async(CommonPool) { doWorkFor1Seconds() } val two = async(CommonPool) { doWorkFor2Seconds() } launch(CommonPool) { val combined = one.await() + "_" + two.await() println("Kotlin Combined : " + combined) } } // The output is // Kotlin Combined : doWorkFor1Seconds_doWorkFor2Seconds
لأن async{}
لأننا نستخدم async{}
، يمكننا الاتصال await()
للحصول على النتيجة.
تعلم سعيد ؛)