combine وzip: دمج تدفقات Flow متعددة
ادمج تدفقات Flow متعددة ونسّق انبعاثاتها معًا باستخدام zip.
combine وzip: دمج تدفقات Flow متعددة درس مجاني في Kotlin Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Kotlin Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Kotlin Academy 4 دروس في المجموع.
لماذا ندمج التدفقات؟
غالبًا ما تحتاج التطبيقات الفعلية إلى دمج عدة تدفقات من البيانات: تفضيلات المستخدم مع بيانات الشبكة، وحقول النموذج مع حالة التحقق. يوفر Kotlin Flow معاملات zip وcombine وmerge لهذا الغرض.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
val names = flowOf("Alice", "Bob", "Carol")
val ages = flowOf(30, 25, 35)
names.zip(ages) { name, age -> "$name is $age" }
.collect { println(it) }
}zip: القيم المنبعثة المقترنة
يقترن zip بالقيم المنبعثة واحدًا لواحد وبالترتيب. ويتوقف عند انتهاء التدفق الأقصر.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
val a = flowOf(1, 2, 3, 4) // 4 elements
val b = flowOf("a", "b", "c") // 3 elements — zip stops here
a.zip(b) { n, s -> "$n-$s" }
.collect { println(it) } // 1-a, 2-b, 3-c
}combine: أحدث القيم
يُصدر combine قيمة جديدة كلما أصدر أي تدفق قيمة، مستخدمًا أحدث قيمة من كل تدفق. ويجب أن يكون كلا التدفقين قد أصدر قيمة واحدة على الأقل.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
val flow1 = MutableStateFlow(1)
val flow2 = MutableStateFlow("a")
combine(flow1, flow2) { n, s -> "$n-$s" }
.take(1)
.collect { println(it) } // 1-a
}الفرق بين combine وzip
zip: ينتظر زوجًا متطابقًا. combine: يُطلِق تحديثًا عند كل تغيير مستخدمًا أحدث القيم. استخدم combine لواجهات المستخدم التفاعلية، مثل حقلي نموذج، واستخدم zip للاقتران التسلسلي.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
// zip: 1-a, 2-b
val nums = flowOf(1, 2).zip(flowOf("a", "b")) { n, s -> "$n-$s" }
nums.collect { println("zip: $it") }
// combine fires more:
combine(flowOf(1, 2), flowOf("a")) { n, s -> "$n-$s" }
.collect { println("combine: $it") }
}merge: تداخل التدفقات
يُصدر merge القيم من عدة تدفقات فور وصولها، من دون إقران؛ لذلك يعتمد ترتيب الناتج على توقيت الإصدار.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
val a = flow { emit("A1"); delay(50); emit("A2") }
val b = flow { delay(25); emit("B1") }
merge(a, b).collect { println(it) } // A1, B1, A2
}combine مع 3 تدفقات أو أكثر
يدعم combine عدة تدفقات. مرّرها باستخدام vararg، وستتلقى lambda جميع أحدث القيم.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
val a = MutableStateFlow("hello")
val b = MutableStateFlow(42)
val c = MutableStateFlow(true)
combine(a, b, c) { s, n, flag -> "$s-$n-$flag" }
.take(1)
.collect { println(it) } // hello-42-true
}flatMapMerge: التدفقات الداخلية المتزامنة
يحوّل flatMapMerge كل عنصر إلى تدفق، ثم يجمع جميع التدفقات الداخلية بشكل متزامن ويدمج نواتجها.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
(1..3).asFlow()
.flatMapMerge { n ->
flow { delay(100L - n * 10); emit("result-$n") }
}
.collect { println(it) }
}flatMapLatest: الإلغاء عند إصدار قيمة جديدة
يلغي flatMapLatest التدفق الداخلي الحالي عند وصول عنصر جديد من المنبع، وهو مثالي للبحث أثناء الكتابة.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
flowOf("k", "ko", "kot", "kotl", "kotli", "kotlin")
.flatMapLatest { query ->
flow {
delay(50) // simulate debounced search
emit("Result for: $query")
}
}
.collect { println(it) } // only "Result for: kotlin"
}zip لاقتران المعاملات
استخدم zip لاقتران الأحداث من تدفقين، مثل إجراءات المستخدم مع تأكيدات الخادم، لضمان تطابق واحد لواحد.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
val orders = flowOf("Order1", "Order2", "Order3")
val confirmations = flowOf("Confirmed", "Confirmed", "Rejected")
orders.zip(confirmations) { order, status -> "$order: $status" }
.collect { println(it) }
}combine للتحقق من صحة النموذج
ادمج تدفقي اسم المستخدم وكلمة المرور لحساب صلاحية النموذج تفاعليًا، بحيث يُحدَّث الحساب كلما تغير أي من الحقلين.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
val username = MutableStateFlow("")
val password = MutableStateFlow("")
val isValid = combine(username, password) { u, p ->
u.length >= 3 && p.length >= 8
}
username.value = "alice"
password.value = "secure123"
println(isValid.first()) // true
}onEach + combine للتحميل من مصادر متعددة
ادمج علامة تحميل مع تدفق بيانات لإنتاج كائن حالة واحد لواجهة المستخدم من عدة مصادر مستقلة.
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
data class UI(val loading: Boolean, val data: String)
fun main() = runBlocking {
val loading = MutableStateFlow(true)
val data = MutableStateFlow("")
combine(loading, data) { l, d -> UI(l, d) }
.take(2)
.collect { println(it) }
data.value = "result"
loading.value = false
}تحقق سريع
ما الفرق الأساسي بين zip وcombine؟
مراجعة
يقترن zip بالقيم المنبعثة بالتتابع، بينما يُطلِق combine تحديثًا عند أي تغيير مستخدمًا أحدث القيم، ويدمج merge التدفقات المستقلة بالتناوب، ويلغي flatMapLatest التدفقات الداخلية القديمة. اختر المعامل وفقًا لحاجتك إلى الاقتران أو التفاعلية.
الأسئلة الشائعة
هل درس «combine وzip: دمج تدفقات Flow متعددة» مجاني؟
نعم — نص درس «combine وzip: دمج تدفقات Flow متعددة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Kotlin Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Kotlin Academy 4 دروس في المجموع.
ماذا ستتعلم في «combine وzip: دمج تدفقات Flow متعددة»؟
ادمج تدفقات Flow متعددة ونسّق انبعاثاتها معًا باستخدام zip. تتمرن على Kotlin Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Kotlin Academy؟
لا تُشترط خبرة سابقة. Kotlin Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «combine وzip: دمج تدفقات Flow متعددة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Kotlin Academy هذا؟
نعم. كل درس في Kotlin Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- معاملات Flow: map وfilter وtransform وtake
- catch وonCompletion: معالجة الأخطاء في Flow
- combine وzip: دمج تدفقات Flow متعددة
- flowOn وbuffer: السياق والضغط العكسي