Async: Future, async & await
Memahami pemrograman asinkron: Future, async/await, menangani error, menjalankan tugas bersamaan dengan Future.wait, timeout, dan event loop.
Mengapa asinkron?
Mengambil data dari internet, membaca berkas besar, atau query database butuh waktu. Jika program menunggu sambil berhenti total, aplikasimu terasa macet. Pemrograman asinkron memungkinkan program melanjutkan pekerjaan lain sambil menunggu operasi lambat itu selesai.
Analogi: memesan kopi di kafe. Kamu dapat nomor antrean (Future), lalu duduk dan membaca; saat kopi siap, kamu dipanggil. Kamu tidak berdiri menatap barista.
Future: nilai yang akan datang
Sebuah Future<T> mewakili hasil bertipe T yang belum tersedia sekarang, tetapi akan ada (atau gagal) nanti. Statusnya: belum selesai, selesai dengan nilai, atau selesai dengan error.
Future<String> ambilNama() {
return Future.delayed(Duration(seconds: 1), () => 'Budi');
}
async dan await
Cara paling mudah memakai Future: async pada function, await di depan Future:
Future<void> main() async {
print('Mulai');
String nama = await ambilNama(); // tunggu di sini, tetapi program lain tidak macet
print('Halo, $nama');
print('Selesai');
}
Urutan cetak: Mulai → (1 detik) → Halo, Budi → Selesai. Kode setelah await baru jalan ketika Future selesai.
- Function bertanda
asyncotomatis mengembalikanFuture. awaithanya boleh dipakai di dalam functionasync.- Function tanpa nilai kembalian ditulis
Future<void>.
Menangani error
Future<int> ambilUmur(String id) async {
await Future.delayed(Duration(milliseconds: 300));
if (id.isEmpty) throw ArgumentError('id kosong');
return 25;
}
Future<void> main() async {
try {
var umur = await ambilUmur('');
print(umur);
} on ArgumentError catch (e) {
print('Gagal: ${e.message}');
} finally {
print('Beres');
}
}
Error di dalam Future ditangani dengan try/catch biasa saat memakai await. Alternatifnya: .catchError(...) atau .then(...).
Berurutan vs bersamaan
// Berurutan: total 2 detik
var a = await tugas(1); // 1 detik
var b = await tugas(2); // 1 detik
// Bersamaan: total 1 detik
var hasil = await Future.wait([tugas(1), tugas(2)]);
print(hasil); // [hasil1, hasil2]
Jika dua pekerjaan tidak saling bergantung, jalankan bersamaan dengan Future.wait supaya lebih cepat.
Berbagai cara membuat Future
| Cara | Fungsi |
|---|---|
Future.value(5) | Future yang langsung selesai dengan nilai |
Future.delayed(durasi, fungsi) | Jalankan setelah jeda (simulasi proses lambat) |
Future.error(e) | Future yang gagal |
function async | Cara umum menulis Future |
Timeout
try {
var data = await ambilNama().timeout(Duration(seconds: 3));
} on TimeoutException {
print('Terlalu lama'); // import 'dart:async'
}
Event loop singkat
Dart berjalan di satu thread dengan event loop: antrean tugas yang dikerjakan satu per satu. await tidak memblokir thread; ia menyerahkan kontrol kembali ke event loop sampai Future selesai. Karena itu operasi I/O asinkron sangat efisien. Untuk pekerjaan berat yang membakar CPU, gunakan isolate (Isolate.run).
Kebiasaan baik
- Selalu
awaitFuture yang penting; jangan dibiarkan (lupa menunggu sering jadi bug). - Bungkus
awaityang bisa gagal dengantry/catch. - Pakai
Future.waituntuk tugas independen.
Error umum
The await expression can only be used in an async function.→ lupa menandai function denganasync.- Mencetak
Instance of 'Future<String>'→ lupaawait. Unhandled exceptiondari Future → tidak ada try/catch atau catchError.