launch — แก่นสาร การเริ่มต้น coroutine แบบ fire-and-forget และการทำงาน

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

launch — Coroutine Builder ใน Kotlin ที่เริ่มต้น coroutine โดยไม่ส่งคืนผลลัพธ์ ส่งคืนออบเจ็กต์ Job เพื่อควบคุมการทำงาน Builder นี้ใช้รูปแบบ fire-and-forget: coroutine เริ่มทำงานในเบื้องหลังและสิ้นสุดโดยอัตโนมัติ ตามเอกสารของ JetBrains, 2024 launch เป็นวิธีหลักในการรันงานแบบขนานใน Kotlin Coroutines

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

  • launch — builder สำหรับเริ่มต้น coroutine โดยไม่ส่งคืนผลลัพธ์ (fire-and-forget)
  • Job — ออบเจ็กต์ควบคุม coroutine ด้วยเมธอด cancel(), join(), isActive
  • launch ทำงานร่วมกับ CoroutineScope เพื่อยกเลิก coroutine ลูกโดยอัตโนมัติ
  • CoroutineStart.LAZY ช่วยให้เลื่อนการทำงานออกไปจนกว่าจะเรียก start() หรือ join() อย่างชัดเจน
  • launch ใน Android ใช้สำหรับบันทึกฐานข้อมูล การเรียกเครือข่าย และอัปเดต UI

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

launch เป็นฟังก์ชันส่วนขยายของ Kotlin ที่สามารถใช้งานได้ผ่านการ import kotlinx.coroutines ซึ่งสร้าง coroutine ใหม่ใน CoroutineScope ที่กำหนด แตกต่างจากฟังก์ชันทั่วไป โค้ดภายใน launch จะทำงานพร้อมกัน — coroutine สามารถหยุดชั่วคราว (suspend) โดยไม่บล็อกเธรดและกลับมาทำงานต่อในภายหลัง

builder launch เป็นบล็อกพื้นฐานของโมเดล coroutine ใน Kotlin มันไม่ส่งคืนค่าที่คำนวณได้แต่ส่งคืนออบเจ็กต์ Job ที่ช่วยให้ควบคุมการทำงานของ coroutine ได้ coroutine ลูกทั้งหมดที่เริ่มต้นผ่าน launch ภายใน coroutine อื่นจะถูกผูกกับ coroutine แม่

ไวยากรณ์และพารามิเตอร์ของ launch

builder launch ถูกกำหนดเป็นฟังก์ชัน inline ที่มีพารามิเตอร์หลายตัว: CoroutineScope, CoroutineContext, CoroutineStart และบล็อก suspend พารามิเตอร์มีค่าเริ่มต้น ทำให้ 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 — ออบเจ็กต์ที่ส่งคืนซึ่งแสดงถึงวงจรชีวิตของ coroutine 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 รองรับลำดับชั้น: ถ้า coroutine แม่ถูกยกเลิก coroutine ลูกทั้งหมดจะถูกยกเลิกโดยอัตโนมัติ SupervisorJob เปลี่ยนพฤติกรรมนี้ — coroutine ลูกจะไม่ถูกยกเลิกเมื่อหนึ่งในนั้นล้มเหลว

การทำงานพร้อมกันแบบมีโครงสร้างใน launch

การทำงานพร้อมกันแบบมีโครงสร้างหมายความว่า coroutine แต่ละตัวเริ่มต้นภายใน CoroutineScope ที่เฉพาะเจาะจง และ scope จะไม่เสร็จสิ้นจนกว่า coroutine ลูกทั้งหมดจะทำงานเสร็จ launch สนับสนุนหลักการนี้อย่างเต็มที่ — coroutine ที่เริ่มต้นภายใน coroutine อื่นจะเป็น coroutine ลูก

การเรียก launch แบบซ้อน

ด้วยการเรียก launch แบบซ้อน จะเกิดโครงสร้างต้นไม้ของ coroutine coroutine แม่รอให้ coroutine ลูกทั้งหมดทำงานเสร็จ ซึ่งรับประกันลำดับการทำงานที่คาดเดาได้และทำให้การจัดการทรัพยากรง่ายขึ้น

kotlin
fun main() = runBlocking {
    launch {
        launch {
            delay(1000L)
            println("ลูก 1 เสร็จสิ้น")
        }
        launch {
            delay(500L)
            println("ลูก 2 เสร็จสิ้น")
        }
        println("ลูกทั้งหมดเสร็จสิ้นก่อนบรรทัดนี้")
    }
}

พฤติกรรมนี้แตกต่างจากการทำงานพร้อมกันแบบเธรด ซึ่งเธรดลูกไม่ผูกกับเธรดแม่ ใน coroutine แม่จะไม่เสร็จสิ้น จนกว่า coroutine ลูกทั้งหมดจะทำงานเสร็จ

การจัดการข้อยกเว้นใน launch

การจัดการข้อยกเว้นใน launch ขึ้นอยู่กับประเภทของ Job สำหรับ Job ปกติ ข้อยกเว้นจะแพร่กระจายไปยัง coroutine แม่และยกเลิกมัน สำหรับ SupervisorJob หรือ SupervisorScope ข้อยกเว้นจะถูกแยก — ข้อผิดพลาดใน coroutine ลูกหนึ่งตัวไม่ส่งผลกระทบต่อตัวอื่น

kotlin
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
    try {
        riskyOperation()
    } catch (e: Exception) {
        println("จับได้: ${e.message}")
    }
}
scope.launch {
    println("สิ่งนี้ยังคงทำงานได้ด้วย SupervisorJob")
}

สำหรับการจัดการข้อยกเว้นที่ไม่ถูกจับในระดับโลก จะใช้ CoroutineExceptionHandler มันจับข้อยกเว้นที่ไม่ได้รับการจัดการภายใน coroutine และช่วยให้บันทึกข้อผิดพลาดโดยไม่ทำให้แอปพลิเคชันหยุดทำงาน

ตัวอย่างการใช้งาน launch ใน Android

ใน Android launch ถูกใช้ทุกที่: จาก ViewModel ถึง WorkManager รูปแบบหลักคือการใช้ lifecycleScope ใน Fragment และ viewModelScope ใน ViewModel เพื่อยกเลิก coroutine โดยอัตโนมัติเมื่อวงจรชีวิตของคอมโพเนนต์สิ้นสุด

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 ยกเลิก coroutine โดยอัตโนมัติเมื่อ ViewModel ถูกทำลาย ซึ่งช่วยลดการรั่วไหลและรับประกันว่าการทำงานเบื้องหลังจะไม่ดำเนินต่อหลังจากสูญเสียบริบท นอกจากนี้ สามารถใช้ withContext เพื่อสลับระหว่าง dispatcher

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

launch แตกต่างจาก async ใน Kotlin Coroutines อย่างไร?

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

จะยกเลิก coroutine ที่เริ่มต้นผ่าน launch ได้อย่างไร?

เรียก job.cancel() บนออบเจ็กต์ Job ที่บันทึกไว้ สำหรับการยกเลิกกลุ่ม ให้ยกเลิก CoroutineScope ทั้งหมดผ่าน scope.cancel() coroutine ต้องให้ความร่วมมือ — ตรวจสอบ isActive หรือใช้ฟังก์ชัน suspend ที่ยกเลิกได้

จะทำอย่างไรถ้า launch ขว้างข้อยกเว้น?

ใช้ try-catch ภายในบล็อก launch หรือส่ง CoroutineExceptionHandler ใน CoroutineContext สำหรับการแยกข้อผิดพลาด ให้ใช้ SupervisorJob — แล้วข้อยกเว้นใน coroutine ลูกหนึ่งตัวจะไม่ยกเลิกตัวอื่น

สามารถใช้ launch โดยไม่มี CoroutineScope ได้หรือไม่?

ไม่ launch เป็นฟังก์ชันส่วนขยายของ CoroutineScope หากไม่มี scope coroutine จะไม่สามารถปฏิบัติตามหลักการทำงานพร้อมกันแบบมีโครงสร้างได้ ใช้ GlobalScope.launch ด้วยความระมัดระวัง — มันสร้าง coroutine ที่ไม่ผูกกับวงจรชีวิต

สามารถรัน launch coroutine พร้อมกันได้กี่ตัว?

จำนวนถูกจำกัดโดยพูลเธรดของ dispatcher Dispatchers.Default ใช้เธรดเท่ากับจำนวนแกน CPU Dispatchers.IO รองรับสูงสุด 64 เธรด หากเริ่มต้น coroutine มากขึ้น พวกมันจะถูกจัดคิว

สรุป

  • launch — builder หลักสำหรับ coroutine แบบ fire-and-forget ส่งคืนออบเจ็กต์ Job
  • Job ให้เมธอดควบคุม: cancel(), join(), isActive, isCancelled, isCompleted
  • การทำงานพร้อมกันแบบมีโครงสร้าง รับประกันการยกเลิก coroutine ลูกเมื่อแม่ถูกยกเลิก
  • การจัดการข้อยกเว้น ขึ้นอยู่กับประเภท Job: ปกติแพร่กระจายข้อผิดพลาด SupervisorJob แยกออก
  • lifecycleScope และ viewModelScope — โซลูชันพร้อมใช้สำหรับเริ่มต้น coroutine ใน Android
  • CoroutineStart.LAZY เลื่อนการทำงานจนกว่าจะเรียก start() หรือ join() อย่างชัดเจน
  • launch ใน Android ใช้สำหรับคำขอเครือข่าย การเขียนฐานข้อมูล การวิเคราะห์ และแคช

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

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

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

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