async & await
Menulis kode async yang terlihat sinkron dengan async/await.
Kode async yang terbaca seperti biasa
.then() bisa dipakai, tapi rantai callback cepat menjadi labirin. async/await adalah gula sintaks yang membuat kode asynchronous terlihat dan terasa seperti kode biasa berurutan, sambil tetap non-blocking di balik layar.
Analogi: .then() itu seperti meninggalkan pesan "telpon aku kalau sudah sampai" lalu menebak-nebak. await itu seperti menunggu di lobi sambil baca majalah: kamu diam di situ, tapi tidak menghalangi orang lain lewat.
Kenapa async/await ada?
Karena otak manusia berpikir sekuensial: langkah 1, lalu 2, lalu 3. Callback memaksa otak berpikir terbalik (inside-out). async/await mengembalikan alur natural tanpa mengorbankan kinerja async.
Bentuk dasar
Future<String> ambilNama() async {
await Future.delayed(Duration(seconds: 2));
return 'Budi';
}
Future<void> main() async {
print('Mulai...');
String nama = await ambilNama(); // TUNGGU di sini, tanpa freeze
print('Nama: $nama');
print('Selesai.');
}Tiga kata kunci:
asyncpada fungsi: "fungsi ini asynchronous, akan mengembalikan Future".awaitpada Future: "tunggu sampai selesai, lalu lanjutkan dengan nilainya".- Fungsi
asyncselalu mengembalikanFuture<T>, bahkan jika kamureturnnilai biasa.
Output: "Mulai...", (2 detik) "Nama: Budi", "Selesai." Terlihat berurutan, tapi thread tidak diblokir selama menunggu.
Contoh kedua, beberapa await berurutan vs paralel:
Future<int> ambilA() async {
await Future.delayed(Duration(seconds: 1));
return 10;
}
Future<int> ambilB() async {
await Future.delayed(Duration(seconds: 1));
return 20;
}
Future<void> main() async {
// BERURUTAN: total 2 detik
int a = await ambilA();
int b = await ambilB();
print('Berurutan: ${a + b}');
// PARALEL: total 1 detik (jalan bersamaan!)
var hasil = await Future.wait([ambilA(), ambilB()]);
print('Paralel: ${hasil[0] + hasil[1]}');
}await berurutan menunggu satu per satu. Future.wait menjalankan semuanya bersamaan dan menunggu semuanya selesai. Untuk request independen, paralel bisa 2-3x lebih cepat.
async* dan yield (sekilas)
Ada juga async* untuk fungsi yang menghasilkan banyak nilai seiring waktu (Stream), memakai yield bukan return. Detailnya di modul Stream; cukup tahu istilahnya sekarang.
Kesalahan umum
1. await di fungsi yang tidak async
// SALAH
// void main() {
// await Future.delayed(Duration(seconds: 1)); // ERROR
// }// BENAR
Future<void> main() async {
await Future.delayed(Duration(seconds: 1));
print('1 detik berlalu');
}2. Lupa await sehingga mendapat Future, bukan nilai
// SALAH: dapat Future<String>, bukan String
Future<String> ambilNama() async => 'Budi';
Future<void> main() async {
var nama = ambilNama(); // Future<String>!
// print(nama.length); // ERROR
print(nama); // Instance of 'Future<String>'
}// BENAR
Future<void> main() async {
var nama = await ambilNama(); // String
print(nama.length); // 4
}Ini error paling umum di dunia async Dart. Kalau melihat Instance of 'Future<...>', 99% karena lupa await.
3. await berurutan untuk hal yang bisa paralel
// Lambat: 3 detik untuk 3 request independen
// var a = await req1(); var b = await req2(); var c = await req3();// Cepat: ~1 detik
Future<void> main() async {
var semua = await Future.wait([req1(), req2(), req3()]);
print(semua);
}
Future<String> req1() async {
await Future.delayed(Duration(seconds: 1));
return 'satu';
}
Future<String> req2() async {
await Future.delayed(Duration(seconds: 1));
return 'dua';
}
Future<String> req3() async {
await Future.delayed(Duration(seconds: 1));
return 'tiga';
}Kesimpulan
async menandai fungsi async, await menunggu Future dengan gaya sekuensial, Future.wait untuk paralel. Aturan emas: fungsi async mengembalikan Future, dan jangan lupa await saat butuh nilainya.
Catatan teknis:
awaittidak memblokir thread; ia "menangguhkan" fungsi dan mengembalikan kontrol ke event loop. Inilah alasan UI Flutter tetap responsif saat menunggu network.
Tantangan
Rangkaian API semu
Buat getUser() (1 detik → "Budi") dan getSaldo(String user) (1 detik → 150000). Di main() async, panggil berurutan lalu cetak "Budi punya Rp150000".
// TODO: getUser, getSaldo
Future<void> main() async {
// TODO
}