dartasyncawaitMahir5 mnt baca

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

dart
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:

  • async pada fungsi: "fungsi ini asynchronous, akan mengembalikan Future".
  • await pada Future: "tunggu sampai selesai, lalu lanjutkan dengan nilainya".
  • Fungsi async selalu mengembalikan Future<T>, bahkan jika kamu return nilai biasa.

Output: "Mulai...", (2 detik) "Nama: Budi", "Selesai." Terlihat berurutan, tapi thread tidak diblokir selama menunggu.

Contoh kedua, beberapa await berurutan vs paralel:

dart
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

dart
// SALAH
// void main() {
//   await Future.delayed(Duration(seconds: 1)); // ERROR
// }
dart
// BENAR
Future<void> main() async {
  await Future.delayed(Duration(seconds: 1));
  print('1 detik berlalu');
}

2. Lupa await sehingga mendapat Future, bukan nilai

dart
// 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>'
}
dart
// 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

dart
// Lambat: 3 detik untuk 3 request independen
// var a = await req1(); var b = await req2(); var c = await req3();
dart
// 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: await tidak 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".

text
// TODO: getUser, getSaldo

Future<void> main() async {
  // TODO
}