Async/Await: Esensi, Fungsi async, dan Cara Kerja await

Penulis: IT Sectr Diterbitkan: 2026-03-16 Waktu membaca: 8 mnt

Async/Await adalah sepasang kata kunci untuk menulis kode asinkron dalam gaya sinkron, tersedia di Swift sejak iOS 13 dan di Kotlin dengan coroutine. Menurut Apple Swift Documentation, 2026, Async/Await menggantikan rantai callback dan GCD, membuat kode asinkron menjadi linear dan mudah dibaca. Kata kunci async menandai fungsi sebagai asinkron, sedangkan await menjeda eksekusinya hingga hasil diperoleh.

Poin Penting

  • Async/Await — gula sintaksis untuk kode asinkron tanpa callback bersarang
  • async menandai fungsi sebagai asinkron dan dapat dijeda
  • await menjeda eksekusi fungsi hingga operasi asinkron selesai
  • Task di Swift membuat unit kerja asinkron baru dengan konteks
  • Structured Concurrency memastikan semua tugas anak selesai sebelum tugas induk

Apa itu Async/Await dan Pemrograman Asinkron

Async/Await adalah konstruksi bahasa yang memungkinkan penulisan kode asinkron secara linear seperti kode sinkron. Di Swift, fitur ini hadir di iOS 13 / macOS 10.15 bersama framework Swift Concurrency. Di Kotlin, async/await tersedia melalui library coroutine (kotlinx.coroutines) mulai versi 1.3.

Sebelum async/await, kode asinkron dibangun dengan callback, GCD, atau RxSwift. Rantai callback bersarang menyebabkan callback hell — tingginya tingkat nested yang mempersulit pembacaan dan debugging. Async/Await memecahkan masalah ini dengan memungkinkan fungsi asinkron "menjeda" di titik await dan melanjutkan setelah hasil diperoleh.

Menurut Google (2025), penggunaan async/await di Kotlin mengurangi jumlah baris kode asinkron sebesar 40–60% dibandingkan pendekatan callback. Di Swift, adopsi Swift Concurrency mencapai 68% di antara aplikasi yang dipublikasikan pada tahun 2025. iOS 16 menambahkan dukungan Swift Concurrency di UIKit, SwiftUI, dan Foundation, menjadikan async/await sebagai alat standar untuk semua proyek baru Apple.

Prinsip Kerja: Fungsi yang Dapat Dijeda

Perbedaan utama async/await dari thread adalah penjedeaan tanpa pemblokiran. Ketika fungsi menemukan await, fungsi tersebut dijeda, membebaskan thread saat ini untuk tugas lain. Setelah operasi asinkron selesai, fungsi dilanjutkan di thread yang sama atau thread lain. Ini disebut cooperative multitasking.

Cara Kerja Async/Await: Penjedeaan dan Pelanjutan

Fungsi async dikompilasi menjadi state machine — sebuah finite state machine yang mengelola status eksekusi. Di titik await, compiler menyimpan konteks (variabel lokal, alamat return) dan menyerahkan kendali ke runtime. Ketika hasil siap, runtime mengembalikan konteks dan melanjutkan eksekusi.

Di Swift, state machine ini diimplementasikan di tingkat compiler SIL (Swift Intermediate Language). Di Kotlin — melalui mekanisme Continuation Passing Style (CPS): setiap fungsi suspend menerima parameter tersembunyi Continuation, yang mengembalikan hasil. Kedua pendekatan menjamin kelanjutan yang aman tanpa kebocoran memori.

  • Swift — compiler menerjemahkan fungsi async ke SIL dengan runAsync coroutine frame
  • Kotlin — setiap fungsi suspend menerima Continuation dan mendelegasikan eksekusi ke dispatcher
  • Kedua bahasa — membebaskan thread saat await, tidak memblokir selama menunggu
  • Pengecualian — dilempar melalui mekanisme standar (throws / try-catch)

Async/Await vs Callbacks dan GCD: Perbandingan Pendekatan

Pendekatan callback memerlukan pengiriman closure yang dipanggil setelah operasi selesai. Dengan tiga permintaan berurutan, terjadi tiga tingkat nested dengan penanganan error di masing-masing. Async/Await mengubah tiga permintaan yang sama menjadi tiga baris berurutan dengan satu blok catch terpadu.

GCD (DispatchQueue) mengatasi masalah callback hell melalui antrean serial dan DispatchGroup, tetapi tetap bertele-tele. Untuk tugas sederhana — memuat user, lalu friends, lalu UI — diperlukan pembuatan antrean, grup, dan blok notify. Async/Await menjalankan tugas yang sama dengan tiga baris dalam satu fungsi.

AspekCallbackGCDAsync/Await
NestedDalam (pyramid of doom)Sedang (grup+notify)Linear (flat)
Penanganan ErrorPer-callbackManualTerpadu (try/catch)
PembatalanManualTerbatasTask.cancel()
Thread safetyManualMelalui serial queueMelalui MainActor

Menurut Apple WWDC 2024, Swift Concurrency async/await adalah pendekatan yang direkomendasikan untuk kode baru. GCD tetap digunakan untuk integrasi dengan library C dan skenario low-level spesifik dari penanganan thread.

Swift Concurrency: Task, TaskGroup, dan Actor

Task adalah unit dasar kerja asinkron di Swift. Task dibuat dalam konteks aktor yang ada atau di thread arbitrer. Di dalam Task, fungsi async dapat dipanggil melalui await. TaskGroup memungkinkan menjalankan beberapa tugas anak secara paralel dan mengumpulkan hasilnya — mirip DispatchGroup yang lebih canggih.

Actor adalah reference type yang aman untuk thread, melindungi statusnya dari race condition. Compiler menjamin bahwa akses ke properti actor hanya dimungkinkan melalui panggilan async atau dalam isolasi actor. Actor menggantikan serial DispatchQueue untuk melindungi shared mutable state tanpa kunci manual.

Structured Concurrency

Prinsip Structured Concurrency menyatakan: setiap tugas asinkron memiliki induk, dan induk tidak selesai sampai semua anaknya selesai. Jika tugas A menjalankan Task { await B() }, maka A menunggu B. Ini mencegah kebocoran tugas dan memastikan lifecycle yang dapat diprediksi.

Async/Await di Kotlin dengan Coroutine

Di Kotlin, async/await diimplementasikan melalui coroutine — thread ringan bahasa. Fungsi ditandai dengan kata kunci suspend (analog dengan async di Swift). Untuk menjalankan digunakan launch (fire-and-forget) atau async (dengan hasil). Await dipanggil untuk mendapatkan hasil dari async.

Dispatcher menentukan di kumpulan thread mana coroutine dijalankan: Dispatchers.Main untuk UI, Dispatchers.IO untuk jaringan/disk, dan Dispatchers.Default untuk tugas intensif CPU. Structured Concurrency dijamin melalui CoroutineScope — ketika scope dibatalkan, semua coroutine anak juga dibatalkan.

Menurut JetBrains (2025), 97% aplikasi Android di Google Play menggunakan kotlinx.coroutines, dan 82% di antaranya menggunakan async/await untuk permintaan jaringan. Coroutine telah menjadi standar de facto untuk pemrograman asinkron di Android. Kotlin Multiplatform juga mendukung coroutine, memungkinkan penggunaan kode asinkron bersama di Android, iOS, dan sisi server.

Contoh Kode dengan Async/Await di Swift dan Kotlin

Mari kita lihat dua contoh untuk setiap bahasa: pemuatan data berurutan dan permintaan paralel dengan TaskGroup atau async/await.

Swift: panggilan async berurutan

await menjeda eksekusi hingga data pengguna diperoleh, kemudian hingga teman-teman diperoleh. Tidak ada closure bersarang.

swift
func loadProfile() async throws -> Profile {
    let user = try await api.fetchUser()
    let friends = try await api.fetchFriends(for: user.id)
    return Profile(user: user, friends: friends)
}

Swift: permintaan paralel dengan TaskGroup

TaskGroup menjalankan tugas secara paralel dan mengumpulkan hasil dalam array. Urutan hasil mungkin tidak sesuai dengan urutan peluncuran.

swift
func loadParallel() async throws -> [String] {
    await withThrowingTaskGroup(of: String.self) { group in
        group.addTask { try await api.fetchName() }
        group.addTask { try await api.fetchEmail() }
        group.addTask { try await api.fetchAvatar() }
        var results = [String]()
        for try await value in group { results.append(value) }
        return results
    }
}

Kotlin: panggilan berurutan dengan async/await

Fungsi suspend dapat memanggil fungsi suspend lainnya. Analog dengan Swift: panggilan berurutan.

kotlin
suspend fun loadProfile(): Profile {
    val user = api.fetchUser()
    val friends = api.fetchFriends(user.id)
    return Profile(user, friends)
}

Kotlin: permintaan paralel dengan async/await

Di Kotlin, paralelisme dicapai melalui coroutineScope dengan async untuk setiap permintaan.

kotlin
suspend fun loadParallel(): List<String> = coroutineScope {
    val name = async { api.fetchName() }
    val email = async { api.fetchEmail() }
    val avatar = async { api.fetchAvatar() }
    listOf(name.await(), email.await(), avatar.await())
}

Kesalahan Umum dan Keterbatasan Async/Await

Task { } yang terlupakan — fungsi asinkron tidak dapat dipanggil dari konteks sinkron tanpa dibungkus dalam Task. Di Swift, ini menghasilkan error kompilasi. Di Kotlin, diperlukan peluncuran melalui lifecycleScope atau viewModelScope. Mencoba memanggil fungsi suspend dari fungsi biasa tidak akan dikompilasi.

Penggunaan async berlebihan tanpa kebutuhan

Tidak setiap fungsi perlu dibuat asinkron. Tugas intensif CPU tanpa I/O tidak mendapat manfaat dari async — lebih baik dijalankan di DispatchQueue dengan QoS .userInitiated. Async/Await dioptimalkan untuk operasi I/O-bound: jaringan, disk, penantian.

Memblokir thread utama melalui .result

Penggunaan .result di thread utama (menunggu sinkron hasil fungsi async) menyebabkan pemblokiran. Di Swift, Task.synchronousWait tidak direkomendasikan oleh Apple. Di Kotlin, runBlocking di thread utama adalah antipattern — gunakan lifecycleScope.

Kebocoran Task saat pembatalan

Jika Task tidak disimpan dalam properti kelas, setelah keluar dari konteks, Task akan dibatalkan. Di Swift, Task bersifat scoped — siklus hidupnya terikat pada konteks pembuatnya. Simpan Task dalam properti jika diperlukan operasi berumur panjang.

Pertanyaan yang Sering Diajukan

Apa perbedaan async/await dengan DispatchQueue?

Async/Await adalah konstruksi bahasa yang tidak memerlukan pembuatan antrean. DispatchQueue adalah API sistem untuk mengelola thread. Async/await dikompilasi menjadi state machine di tingkat bahasa, GCD — menjadi syscall di tingkat OS.

Apakah await memblokir thread?

Tidak — await menjeda fungsi, tetapi membebaskan thread untuk tugas lain. Setelah operasi selesai, fungsi dilanjutkan di thread mana pun yang tersedia dari pool.

Bisakah tugas async dibatalkan?

Ya — melalui Task.cancel() di Swift atau Job.cancel() di Kotlin. Pembatalan menyebar ke semua tugas anak sesuai Structured Concurrency. Kode memeriksa flag pembatalan melalui Task.isCancelled atau ensureActive().

Apa itu MainActor di Swift?

MainActor adalah actor yang properti dan metodenya selalu dijalankan di thread utama. Dengan menandai fungsi @MainActor, Anda menjamin bahwa pembaruan UI terjadi di thread yang benar, menggantikan DispatchQueue.main.async.

Di bahasa mana saja ada async/await?

Async/Await tersedia di Swift (iOS 13+), Kotlin (melalui kotlinx.coroutines), Dart (Flutter), JavaScript/TypeScript, Python, C#, Rust, dan Go (melalui goroutine dengan gula sintaksis).

Kesimpulan

  • Async/Await — konstruksi bahasa untuk kode asinkron linear tanpa callback hell
  • Swift Concurrency menyediakan Task, TaskGroup, Actor, dan Structured Concurrency
  • Coroutine Kotlin menggunakan fungsi suspend, Dispatchers, dan coroutine scope
  • Penjedeaan tanpa pemblokiran — perbedaan utama async/await dari thread dan antrean
  • Structured Concurrency menjamin penyelesaian semua tugas anak sebelum tugas induk
  • Async/Await vs GCD — yang pertama lebih disukai untuk kode baru, yang kedua untuk legacy dan low-level
  • MainActor di Swift dan Dispatchers.Main di Kotlin melindungi thread UI dari operasi latar belakang

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga