0Pricing
Kotlin Academy · บทเรียน

combine และ zip: รวม Flow หลายสาย

รวม Flow หลายสายและจับคู่ค่าที่ปล่อยออกมาด้วย zip

combine และ zip: รวม Flow หลายสาย เป็นบทเรียน Kotlin Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Kotlin Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดจึงต้องรวมโฟลว์

แอปจริงมักต้องรวมกระแสข้อมูลหลายแหล่งเข้าด้วยกัน เช่น การตั้งค่าของผู้ใช้กับข้อมูลจากเครือข่าย หรือช่องกรอกข้อมูลกับสถานะการตรวจสอบ Kotlin มีโฟลว์ที่จัดเตรียม 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 และแลมบ์ดาจะได้รับค่าล่าสุดทั้งหมด

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 หลายสาย” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Kotlin Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Kotlin Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “combine และ zip: รวม Flow หลายสาย”

รวม Flow หลายสายและจับคู่ค่าที่ปล่อยออกมาด้วย zip คุณปฏิบัติ Kotlin Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Kotlin Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Kotlin Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “combine และ zip: รวม Flow หลายสาย” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Kotlin Academy นี้ได้ไหม

ได้ บทเรียน Kotlin Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ตัวดำเนินการ Flow: map, filter, transform และ take
  2. catch และ onCompletion: การจัดการข้อผิดพลาดใน Flow
  3. combine และ zip: รวม Flow หลายสาย
  4. flowOn และ buffer: บริบทและแรงดันย้อนกลับ
← กลับไปที่ Kotlin Academy