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
- SupervisorJob vs Job: Isolasi Kegagalan
- CoroutineExceptionHandler: Penangan Global yang Tidak Tertangkap
- Propagasi Exception async/await
- Merancang Arsitektur Coroutine yang Tangguh