dartasyncfutureMahir5 mnt baca

Future Dasar

Nilai yang datang nanti: konsep Future di Dart.

Janji akan nilai di masa depan

Program sering menunggu: mengambil data dari internet, membaca file, jeda 2 detik. Kalau program berhenti total menunggu, aplikasi macet (freeze). Future adalah cara Dart berkata: "nilainya belum ada, tapi AKAN ada. Kerjakan yang lain dulu, aku kabari kalau sudah siap."

Analogi: Future itu seperti nomor antrean di bank. Kamu tidak berdiri mematung di depan teller; kamu pegang nomor, duduk, main HP, dan dipanggil saat giliran tiba. Nomor antrean = Future, giliran dipanggil = nilai siap.

Kenapa Future ada?

Karena operasi I/O (network, file, database) lambat dibanding CPU, ribuan kali lebih lambat. Menunggu sambil diam membuang waktu. Future + async memungkinkan satu thread menangani banyak pekerjaan menunggu secara bergantian, tanpa thread tambahan yang berat.

Future dasar

dart
// Fungsi yang mengembalikan Future<String>: butuh 2 detik
Future<String> ambilNama() {
  return Future.delayed(Duration(seconds: 2), () => 'Budi');
}

void main() {
  print('Mulai...');
  ambilNama().then((nama) {
    print('Nama diterima: $nama');
  });
  print('Tidak menunggu, langsung lanjut!');
}

Output: "Mulai...", "Tidak menunggu, langsung lanjut!", (2 detik kemudian) "Nama diterima: Budi". Method .then() mendaftarkan callback yang jalan nanti saat Future selesai.

Tiga status Future:

  • Uncompleted: masih menunggu (seperti nomor antrean di tangan).
  • Completed with value: berhasil, nilainya tersedia.
  • Completed with error: gagal, error-nya tersedia.

Contoh kedua, Future yang gagal:

dart
Future<String> ambilData(bool gagal) {
  return Future.delayed(Duration(seconds: 1), () {
    if (gagal) throw Exception('Jaringan putus!');
    return 'Data OK';
  });
}

void main() {
  ambilData(true).then((data) {
    print(data);
  }).catchError((e) {
    print('Gagal: $e');
  });
}

.catchError() menangani kegagalan, seperti catch biasa tapi untuk dunia async.

Future.value dan Future.error

Untuk membuat Future yang langsung selesai (berguna di testing):

dart
void main() {
  Future.value(42).then((n) => print('Langsung: $n'));
  Future.error('oops').catchError((e) => print('Error: $e'));
}

Kesalahan umum

1. Mengira .then() menunggu

dart
// SALAH: berharap berurutan
void main() {
  String? hasil;
  Future.delayed(Duration(seconds: 1), () => 'Budi').then((n) {
    hasil = n;
  });
  // print(hasil!.length); // ERROR: hasil masih null di sini!
  print('hasil belum siap saat baris ini jalan');
}
dart
// BENAR: pakai nilai DI DALAM then, atau pakai async/await
void main() {
  Future.delayed(Duration(seconds: 1), () => 'Budi').then((n) {
    print('Panjang nama: ${n.length}'); // 4, di dalam then
  });
}

Kode setelah .then() jalan SEBELUM Future selesai. Nilai Future hanya valid di dalam callback.

2. Lupa menangani error

Future yang gagal tanpa .catchError() menyebabkan unhandled async error yang sulit dilacak. Selalu pasangkan dengan penanganan error, atau pakai try-catch dengan async/await (modul berikutnya).

3. Callback hell: then bertingkat

dart
// Bisa, tapi sulit dibaca
void main() {
  Future.value(1).then((a) {
    return Future.value(a + 1).then((b) {
      return Future.value(b + 1).then((c) {
        print(c); // 3
      });
    });
  });
}

Rantai then bertingkat adalah alasan async/await diciptakan: kode async yang terlihat sinkron.

Kesimpulan

Future = nilai masa depan dengan 3 status (menunggu/berhasil/gagal). .then() untuk sukses, .catchError() untuk gagal. Ingat: kode di luar callback jalan duluan. Di modul berikutnya, async/await membuat semua ini jauh lebih enak dibaca.

Catatan teknis: Future di Dart berjalan di event loop single-threaded, bukan thread terpisah. Operasi I/O didelegasikan ke sistem, dan callback dijadwalkan kembali saat selesai. Model ini ringan: ribuan Future tidak seberat ribuan thread.

Tantangan

Simulasi unduhan

Buat fungsi unduh(String file) yang mengembalikan Future<String> berisi "$file selesai" setelah 1 detik. Panggil untuk 2 file dan cetak hasilnya dengan then.

text
// TODO: fungsi unduh

void main() {
  // TODO
}