Coroutine Builder: คืออะไร, ประเภทของตัวสร้างโครูทีนและการทำงาน

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-06-21 เวลาอ่าน: 8 นาที

Coroutine Builder — ฟังก์ชันของ Kotlin Coroutines ที่สร้างและเริ่มทำงานโครูทีน โดยกำหนดวิธีดำเนินการ ตัวสร้าง launch, async, runBlocking และ produce ครอบคลุมสถานการณ์ต่างๆ ตั้งแต่งานพื้นหลังไปจนถึงการคำนวณแบบขนานพร้อมส่งคืนผลลัพธ์ ตามข้อมูลจาก JetBrains, 2024, Coroutine Builder เป็นรากฐานของโมเดลโครูทีน ให้การทำงานพร้อมกันแบบมีโครงสร้างและการจัดการวงจรชีวิต

ประเด็นสำคัญ

  • Coroutine Builder — ฟังก์ชันที่สร้างโครูทีนภายใน CoroutineScope ที่กำหนด
  • launch — เริ่มโครูทีนโดยไม่ส่งคืนผลลัพธ์ ส่งคืนออบเจกต์ Job
  • async — เริ่มโครูทีนโดยส่งคืน Deferred ทำให้สามารถรับผลลัพธ์ผ่าน await()
  • runBlocking — บล็อกเธรดปัจจุบัน ใช้เป็นสะพานระหว่างโค้ดแบบบล็อกและแบบระงับ
  • produce — สร้างโครูทีนพร้อมช่องทางสำหรับสตรีมข้อมูล (เลิกใช้แล้ว แนะนำให้ใช้ Flow)

Coroutine Builder คืออะไร?

Coroutine Builder เป็นฟังก์ชันส่วนขยายของ Kotlin ที่รับ CoroutineScope และบล็อก suspend สร้างและเริ่มโครูทีนใหม่ ตัวสร้างแต่ละตัวกำหนดว่าโครูทีนจะดำเนินการอย่างไร: มีหรือไม่มีการส่งคืนผลลัพธ์ มีการบล็อกเธรดหรือแบบอะซิงโครนัส ตัวสร้างเป็นจุดเริ่มต้นของโมเดลโครูทีนของภาษา

ตัวสร้างทั้งหมดทำงานผ่าน CoroutineScope ซึ่งจัดการวงจรชีวิตของโครูทีนย่อย เมื่อขอบเขตถูกยกเลิก โครูทีนทั้งหมดที่เริ่มผ่านขอบเขตนั้นจะถูกยกเลิกโดยอัตโนมัติ — นี่คือหลักการของ การทำงานพร้อมกันแบบมีโครงสร้าง วิธีการนี้ป้องกันการรั่วไหลของโครูทีนและรับประกันการสิ้นสุดที่คาดเดาได้

kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    // ตัวสร้างทำงานภายใน CoroutineScope
    val job = launch {
        delay(1000L)
        println("โลก!")
    }
    println("สวัสดี,")
    job.join()
}

ประเภทหลักของตัวสร้างโครูทีน

Kotlin มีตัวสร้างโครูทีนในตัวสี่ประเภท: launch, async, runBlocking และ produce แต่ละประเภทมีชนิดส่งคืนและขอบเขตการใช้งานของตนเอง สำหรับการพัฒนาแอปพลิเคชันมือถือ Android ตัวสร้างหลักคือ launch และ async — ทำงานแบบไม่บล็อกและสามารถทำงานร่วมกับคอมโพเนนต์ทางสถาปัตยกรรมได้

ตัวสร้างชนิดส่งคืนการบล็อกเธรดสถานการณ์
launchJobไม่งาน fire-and-forget
asyncDeferred<T>ไม่การคำนวณแบบขนาน
runBlockingTใช่การทดสอบ, ฟังก์ชัน main
produceReceiveChannel<E>ไม่สตรีมมิ่ง (เลิกใช้)

ตัวสร้างแต่ละตัวรับพารามิเตอร์เพิ่มเติม: CoroutineStart (กลยุทธ์การเริ่ม), CoroutineContext (ตัวจัดส่ง, ข้อยกเว้น) และบล็อกโค้ดที่มีชื่อ โดยค่าเริ่มต้น โครูทีนจะเริ่มทันที (CoroutineStart.DEFAULT)

launch: การดำเนินการแบบ fire-and-forget

launch เป็นตัวสร้างที่ใช้มากที่สุดในการพัฒนา Android มันเริ่มโครูทีนที่ไม่ส่งคืนผลลัพธ์ และส่งคืนออบเจกต์ Job สำหรับจัดการวงจรชีวิต นี่เป็นตัวเลือกที่เหมาะสำหรับการดำเนินการที่ต้องการเพียงเอฟเฟกต์ข้างเคียง: บันทึกลงฐานข้อมูล ส่งการวิเคราะห์ อัปเดต UI

ไวยากรณ์และการใช้งาน launch

ตัวสร้าง launch รับ CoroutineScope, CoroutineContext ที่ไม่บังคับ และบล็อก suspend Job ที่ส่งคืนช่วยให้ยกเลิกโครูทีน รอให้เสร็จสมบูรณ์ หรือตรวจสอบสถานะได้

kotlin
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
val job: Job = scope.launch(CoroutineStart.LAZY) {
    val data = fetchFromNetwork()
    saveToDatabase(data)
}
job.start()
job.join()

พารามิเตอร์ CoroutineStart.LAZY เลื่อนการดำเนินการจนกว่าจะเรียก start() หรือ join() อย่างชัดเจน ซึ่งมีประโยชน์สำหรับการเริ่มต้นแบบขี้เกียจและการดำเนินการแบบมีเงื่อนไข สำหรับการดำเนินการทันทีมาตรฐาน ใช้ CoroutineStart.DEFAULT หรือละพารามิเตอร์

async: การคำนวณแบบขนานพร้อมผลลัพธ์

async เป็นตัวสร้างที่ส่งคืน Deferred<T> — สัญญาแบบอะซิงโครนัสของผลลัพธ์ การเรียก await() จะระงับโครูทีนจนกว่าจะได้รับผลลัพธ์ โดยไม่บล็อกเธรด นี่เป็นกลไกหลักสำหรับงานแบบขนานในโครูทีน Kotlin

เริ่มสองคำขอแบบขนาน

async มีประสิทธิภาพโดยเฉพาะเมื่อคุณต้องดำเนินการหลายอย่างที่เป็นอิสระพร้อมกัน ต่างจากการเรียกฟังก์ชัน suspend แบบเรียงลำดับ async จะเริ่มโครูทีนแบบขนาน ลด เวลาในการดำเนินการทั้งหมด

kotlin
suspend fun fetchUserData(): UserData {
    val deferred1 = CoroutineScope(Dispatchers.IO).async { api.getProfile() }
    val deferred2 = CoroutineScope(Dispatchers.IO).async { api.getSettings() }
    val deferred3 = CoroutineScope(Dispatchers.IO).async { api.getNotifications() }
    return UserData(
        profile = deferred1.await(),
        settings = deferred2.await(),
        notifications = deferred3.await()
    )
}

Deferred สืบทอดจาก Job ดังนั้น async จึงรองรับการดำเนินการวงจรชีวิตทั้งหมด: การยกเลิก การรอให้เสร็จสมบูรณ์ การจัดการข้อยกเว้น เมื่อขอบเขตถูกยกเลิก โครูทีน Deferred ย่อยจะถูกยกเลิกโดยอัตโนมัติ

runBlocking: สะพานสู่โลกแบบบล็อก

runBlocking เป็นตัวสร้างเดียวที่บล็อกเธรดปัจจุบันจนกว่าโครูทีนจะเสร็จสมบูรณ์ มันสร้าง CoroutineScope ใหม่และเริ่มโครูทีนที่ส่งเข้าไป บล็อกเธรดที่เรียก ใช้ในจุดเริ่มต้น main(), ในการทดสอบ และเมื่อทำงานร่วมกับโค้ดแบบบล็อก

เมื่อใดที่จำเป็นต้องใช้ runBlocking

runBlocking เหมาะสมในสามสถานการณ์: จุดเริ่มต้นของแอปพลิเคชัน (main), การทดสอบหน่วยของฟังก์ชัน suspend และการทำงานร่วมกับไลบรารีที่ใช้ callback ซึ่งไม่สามารถใช้ suspend ได้ ในโค้ด Android ที่ใช้งานจริง การใช้ runBlocking บนเธรดหลัก ไม่แนะนำอย่างยิ่ง

kotlin
class CoroutineTest {
    @Test
    fun `test suspend function`() = runBlocking {
        val result = mySuspendFunction()
        assertEquals("expected", result)
    }
}

สำหรับการทดสอบ แนะนำให้ใช้ kotlinx-coroutines-test กับ TestCoroutineDispatcher แทน runBlocking — ซึ่งให้การควบคุมเวลาและหลีกเลี่ยงการบล็อกในสภาพแวดล้อมการทดสอบ

วิธีเลือกตัวสร้างที่เหมาะสม

การเลือก Coroutine Builder ขึ้นอยู่กับผลลัพธ์ที่ส่งคืนและสถานการณ์การดำเนินการ หากการดำเนินการไม่ต้องการส่งคืนข้อมูล — ใช้ launch หากคุณต้องการผลลัพธ์ของการดำเนินการแบบอะซิงโครนัส — ใช้ async ใช้ runBlocking เฉพาะเป็นสะพาน และแทนที่ produce ด้วย Flow สำหรับสตรีมแบบรีแอกทีฟ

คำแนะนำเชิงปฏิบัติสำหรับ Android

ในโปรเจกต์ Android ที่ใช้ Kotlin Coroutines คู่ตัวสร้างหลักคือ launch และ async ใช้ launch ใน ViewModel และ UseCases เพื่อเริ่มโครูทีน ในขณะที่ async ใช้สำหรับคำขอแบบขนานไปยังเครือข่ายหรือฐานข้อมูล ไลบรารีสมัยใหม่ (Ktor, Room) รองรับฟังก์ชัน suspend อยู่แล้ว ซึ่ง ลดความจำเป็น ในการใช้ async โดยตรง

  • launch — สำหรับ fire-and-forget (การบันทึก, การวิเคราะห์, แคช)
  • async — สำหรับคำขอแบบขนานพร้อมรวมผลลัพธ์
  • runBlocking — เฉพาะใน main() และการทดสอบ (ไม่ใช้บนเธรด Main ในการใช้งานจริง)
  • produce — แทนที่ด้วย Flow / SharedFlow / StateFlow

คำถามที่พบบ่อย

ความแตกต่างระหว่าง launch และ async ใน Kotlin คืออะไร?

launch ส่งคืน Job และไม่ส่งคืนผลลัพธ์การดำเนินการ ในขณะที่ async ส่งคืน Deferred<T> — ออบเจกต์ที่สามารถรับผลลัพธ์ได้ผ่าน await() ใช้ launch สำหรับการดำเนินการแบบ fire-and-forget และ async สำหรับงานที่ส่งคืนข้อมูล

สามารถใช้ runBlocking ใน Android Activity ได้หรือไม่?

ไม่แนะนำ runBlocking บนเธรดหลักทำให้เกิด ANR และบล็อก UI ให้ใช้ lifecycleScope.launch ภายใน Activity และ Fragment — เป็นโซลูชันในตัวที่ไม่มีการบล็อก

ตัวสร้าง launch ส่งคืนอะไร?

ตัวสร้าง launch ส่งคืนออบเจกต์ Job ซึ่งช่วยให้ควบคุมวงจรชีวิตของโครูทีนได้: ยกเลิก (cancel), รอให้เสร็จ (join), ตรวจสอบสถานะ (isActive, isCompleted, isCancelled)

Deferred ใน Kotlin Coroutines คืออะไร?

Deferred<T> คือสัญญาแบบอะซิงโครนัสของผลลัพธ์ ซึ่งส่งคืนโดยตัวสร้าง async มันสืบทอดจาก Job และเพิ่มเมธอด: await() สำหรับรับผลลัพธ์, getCompleted() สำหรับการเข้าถึงแบบไม่บล็อก, และ getCompletionExceptionOrNull() สำหรับตรวจสอบข้อยกเว้น

วิธีเริ่ม launch แบบหน่วงเวลา?

ใช้พารามิเตอร์ CoroutineStart.LAZY: scope.launch(start = CoroutineStart.LAZY) { ... } จากนั้นเรียก job.start() หรือ job.join() เพื่อดำเนินการจริง ซึ่งมีประโยชน์สำหรับการเริ่มต้นแบบขี้เกียจและการดำเนินการโครูทีนแบบมีเงื่อนไข

สรุป

  • Coroutine Builder — ฟังก์ชันสร้างโครูทีนที่กำหนดการดำเนินการและชนิดส่งคืน
  • launch — ตัวสร้างหลักสำหรับงานที่ไม่มีผลลัพธ์ ส่งคืน Job สำหรับจัดการโครูทีน
  • async — ตัวสร้างสำหรับการคำนวณแบบขนาน ส่งคืน Deferred พร้อมความสามารถ await() ผลลัพธ์
  • runBlocking — ตัวสร้างแบบบล็อกสำหรับ main() และการทดสอบ ไม่แนะนำบนเธรดหลักของ Android
  • การทำงานพร้อมกันแบบมีโครงสร้าง รับประกันการยกเลิกโครูทีนย่อยโดยอัตโนมัติเมื่อยกเลิกขอบเขต
  • produce เลิกใช้แล้ว — ใช้ Flow, SharedFlow หรือ StateFlow สำหรับสตรีมข้อมูลแบบรีแอกทีฟ
  • การเลือกตัวสร้างขึ้นอยู่กับสถานการณ์: fire-and-forget → launch, ข้อมูลขนาน → async, สะพาน → runBlocking

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม