0Pricing
Kotlin Academy · Pelajaran

SupervisorJob vs Job: Isolasi Kegagalan

Gunakan SupervisorJob agar kegagalan satu anak tidak membatalkan coroutine saudara.

SupervisorJob vs Job: Isolasi Kegagalan adalah pelajaran Kotlin Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Kotlin Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Kotlin Academy mencakup 4 pelajaran total.

Propagasi Kegagalan Job Default

Dengan Job biasa, kegagalan turunan membatalkan induknya, yang kemudian membatalkan semua turunan lainnya. Satu kegagalan menjatuhkan seluruh hierarki.

import kotlinx.coroutines.*
fun main() = runBlocking {
    try {
        coroutineScope {
            launch { delay(50); throw RuntimeException("child 1 failed") }
            launch { delay(1000); println("child 2 — never prints") }
        }
    } catch (e: RuntimeException) {
        println("Caught: ${e.message}")
    }
}

Gambaran Umum SupervisorJob

SupervisorJob mengubah aturan: kegagalan turunan NOT membatalkan turunan lain atau induknya. Setiap turunan gagal secara independen.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val supervisor = SupervisorJob()
    val scope = CoroutineScope(coroutineContext + supervisor)
    scope.launch { throw RuntimeException("child 1 failed") }
    scope.launch { delay(100); println("child 2 still runs") }
    delay(200)
    supervisor.cancel()
}

Pembuat supervisorScope

supervisorScope { } membuat cakupan dengan SupervisorJob sebagai induknya. Ini adalah cara idiomatis untuk menjalankan turunan yang independen.

import kotlinx.coroutines.*
fun main() = runBlocking {
    supervisorScope {
        val job1 = launch {
            throw RuntimeException("job1 failed")
        }
        val job2 = launch {
            delay(100)
            println("job2 succeeded")
        }
        job1.join()  // wait for job1 (it failed)
        job2.join()  // job2 is unaffected
    }
}

Menangani Kegagalan Turunan

Dengan supervisorScope, setiap turunan menangani exception-nya sendiri. Exception yang tidak ditangani dalam turunan harus ditangkap pada masing-masing turunan.

import kotlinx.coroutines.*
fun main() = runBlocking {
    supervisorScope {
        val result = async {
            delay(50)
            throw RuntimeException("async failed")
        }
        try {
            result.await()
        } catch (e: RuntimeException) {
            println("Caught from async: ${e.message}")
        }
        println("Scope continues")
    }
}

Job vs SupervisorJob saat Membuat Cakupan

Teruskan SupervisorJob() saat membuat CoroutineScope untuk layanan atau ViewModel yang harus tetap berjalan meskipun turunan tertentu gagal.

import kotlinx.coroutines.*
class MyService {
    private val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())
    fun startTask(name: String) {
        scope.launch {
            if (name == "fail") throw RuntimeException("$name failed")
            println("$name done")
        }
    }
    fun stop() = scope.cancel()
}
fun main() = runBlocking {
    val svc = MyService()
    svc.startTask("fail")
    svc.startTask("ok")
    delay(100)
    svc.stop()
}

viewModelScope Menggunakan SupervisorJob

viewModelScope Android didukung oleh SupervisorJob. Satu peluncuran yang gagal tidak membatalkan coroutine lain milik ViewModel.

import kotlinx.coroutines.*
// Android ViewModel internals:
// val viewModelScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
// Each launch is independent — one failure doesn't crash the ViewModel
fun main() = runBlocking {
    println("viewModelScope = SupervisorJob + Main")
}

Dekomposisi Paralel dengan supervisorScope

Gunakan supervisorScope + async untuk tugas paralel yang sebagian mungkin gagal tanpa memengaruhi tugas lainnya.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val results = supervisorScope {
        val a = async { delay(50); "result-A" }
        val b = async { throw RuntimeException("B failed") }
        val c = async { delay(30); "result-C" }
        listOf(
            runCatching { a.await() },
            runCatching { b.await() },
            runCatching { c.await() }
        )
    }
    results.forEach { println(it) }
}

Kapan Menggunakan Tugas Reguler

Gunakan Job biasa (coroutineScope) ketika semua tugas anak harus berhasil bersama—satu kegagalan harus membatalkan grup. Seperti transaksi: semuanya berhasil atau tidak sama sekali.

import kotlinx.coroutines.*
fun main() = runBlocking {
    try {
        coroutineScope {  // regular Job
            val a = async { delay(50); "A" }
            val b = async { throw RuntimeException("B failed") }
            println(a.await())
            println(b.await())  // throws — cancels a too
        }
    } catch (e: RuntimeException) {
        println("Transaction failed: ${e.message}")
    }
}

Propagasi Pengecualian dalam supervisorScope

Dalam supervisorScope, pengecualian diteruskan ke cakupan hanya jika pengecualian tersebut keluar dari tingkat teratas tugas anak—yaitu, tidak ada try-catch di dalam tugas anak. Induk tidak melihatnya.

import kotlinx.coroutines.*
fun main() = runBlocking {
    supervisorScope {
        // Exception caught inside child — scope unaffected
        launch {
            try { throw RuntimeException("handled") }
            catch (e: Exception) { println("Child caught: ${e.message}") }
        }
        delay(100)
        println("Scope survived")
    }
}

CoroutineExceptionHandler dengan SupervisorJob

Pasang CoroutineExceptionHandler dalam cakupan supervisor untuk mencatat log atau menanggapi kegagalan tugas anak yang tidak tertangani tanpa membuat cakupan mogok.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val handler = CoroutineExceptionHandler { _, e ->
        println("Uncaught: ${e.message}")
    }
    val scope = CoroutineScope(SupervisorJob() + handler)
    scope.launch { throw RuntimeException("unhandled failure") }
    scope.launch { delay(100); println("still running") }
    delay(200)
    scope.cancel()
}

Ringkasan Isolasi Kegagalan

Tugas: satu tugas anak gagal → semuanya gagal. SupervisorJob: tugas anak gagal secara independen. Gunakan supervisor untuk layanan dan ViewModels; gunakan Job biasa untuk grup transaksional.

import kotlinx.coroutines.*
// Decision table:
// coroutineScope { }   -> Job: all-or-nothing
// supervisorScope { }  -> SupervisorJob: independent failures
// CoroutineScope(SupervisorJob()) -> long-lived service
fun main() = runBlocking { println("Pick the right job for the right scope") }

Pemeriksaan Singkat

Cakupan mana yang mencegah kegagalan tugas anak membatalkan tugas-tugas saudaranya?

Ringkasan

Tugas: kegagalan menyebar ke tugas-tugas saudara. SupervisorJob/supervisorScope: kegagalan diisolasi pada setiap tugas anak. Gunakan supervisorScope untuk tugas paralel yang independen; gunakan coroutineScope biasa untuk grup transaksional.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “SupervisorJob vs Job: Isolasi Kegagalan” gratis?

Ya — teks lengkap “SupervisorJob vs Job: Isolasi Kegagalan” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Kotlin Academy, upgrade ke CoddyKit PRO. Kursus Kotlin Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “SupervisorJob vs Job: Isolasi Kegagalan”?

Gunakan SupervisorJob agar kegagalan satu anak tidak membatalkan coroutine saudara. Kamu berlatih Kotlin Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Kotlin Academy?

Tidak diperlukan pengalaman sebelumnya. Kotlin Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.

Berapa lama pelajaran “SupervisorJob vs Job: Isolasi Kegagalan” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Kotlin Academy ini?

Ya. Setiap pelajaran Kotlin Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. SupervisorJob vs Job: Isolasi Kegagalan
  2. CoroutineExceptionHandler: Penangan Global yang Tidak Tertangkap
  3. Propagasi Exception async/await
  4. Merancang Arsitektur Coroutine yang Tangguh
← Kembali ke Kotlin Academy