Async/Await & Promise yang Bertipe

Memahami Promise<T>, menulis fungsi async dengan tipe kembalian yang benar, menunggu banyak promise dengan Promise.all, dan menangani error asynchronous secara aman.

Part 21 dari 24 ± 50 menit Gratis

Promise: janji yang menghasilkan nilai nanti

Operasi seperti memanggil API, membaca file, atau menunggu timer tidak selesai seketika. JavaScript membungkusnya dalam Promise — objek yang "berjanji" memberi hasil di masa depan. TypeScript menambahkan tipe hasilnya: Promise<T> = "janji yang akan menghasilkan T".

const janji: Promise<number> = Promise.resolve(42)

janji.then((n) => {
  console.log(n.toFixed(1))      // n: number — dikenali otomatis
})

async / await

async membuat fungsi selalu mengembalikan Promise; await "menunggu" Promise selesai dan memberi nilainya, sehingga kode asynchronous terbaca seperti kode biasa.

interface Pengguna { id: number; nama: string }

async function ambilPengguna(id: number): Promise<Pengguna> {
  // contoh: seolah memanggil server
  return { id, nama: "User " + id }
}

async function tampilkan() {
  const p = await ambilPengguna(1)      // p: Pengguna  (bukan Promise<Pengguna>)
  console.log(p.nama)
}
tampilkan()

Tipe kembalian fungsi async selalu Promise<...>. Menulis : Promise<Pengguna> berarti fungsi itu return sebuah Pengguna (bukan Promise-nya) — TypeScript membungkusnya otomatis.

Lupa await = bug halus

const p = ambilPengguna(1)
console.log(p.nama)     // ❌ Property 'nama' does not exist on type 'Promise<Pengguna>'. Did you forget to use 'await'?

Di sinilah TypeScript menyelamatkan: di JavaScript biasa ini hanya menghasilkan undefined tanpa peringatan.

Menjalankan beberapa promise sekaligus

const [a, b, c] = await Promise.all([
  ambilPengguna(1),
  ambilPengguna(2),
  ambilPengguna(3),
])
// a, b, c: Pengguna — TypeScript menjaga tipe tiap posisi (tuple)

const campur = await Promise.all([ambilPengguna(1), Promise.resolve("ok"), Promise.resolve(5)])
// [Pengguna, string, number]

Dengan await berurutan, tiap panggilan menunggu yang sebelumnya; Promise.all menjalankan semuanya bersamaan (jauh lebih cepat bila tidak saling bergantung). Variasi lain: Promise.allSettled (tunggu semua, sukses maupun gagal), Promise.race (yang tercepat), Promise.any (sukses pertama).

Menangani error

async function aman(id: number): Promise<Pengguna | null> {
  try {
    return await ambilPengguna(id)
  } catch (e) {                      // e: unknown (di mode strict)
    if (e instanceof Error) console.log("Gagal:", e.message)
    return null
  }
}

Ingat dari bab 6: variabel catch bertipe unknown karena JavaScript boleh melempar apa saja (bahkan string). Selalu persempit dulu (instanceof Error).

Membungkus callback menjadi Promise

function tunggu(ms: number): Promise<void> {
  return new Promise<void>((selesai) => setTimeout(selesai, ms))
}

async function demo() {
  await tunggu(500)
  console.log("setengah detik berlalu")
}

Awaited dan ReturnType

type HasilAmbil = Awaited<ReturnType<typeof ambilPengguna>>   // Pengguna

fetch yang bertipe (di browser/Node 18+)

async function ambilData<T>(url: string): Promise<T> {
  const res = await fetch(url)
  if (!res.ok) throw new Error(`HTTP ${res.status}`)
  return (await res.json()) as T       // ⚠️ 'as T' hanya klaim, bukan jaminan — lihat bab 22
}
const todo = await ambilData<{ id: number; title: string }>("https://jsonplaceholder.typicode.com/todos/1")

Kesalahan umum pemula

  • Lupa await (TypeScript biasanya memperingatkan seperti di atas).
  • Memakai await di dalam forEach — callback-nya tidak ditunggu. Pakai for...of atau Promise.all(arr.map(...)).
  • Tidak menangani error sehingga muncul unhandled rejection.
  • Menganggap as T pada hasil fetch memvalidasi data. Ia tidak — hanya meyakinkan compiler.

Praktikkan langsung, gratis

Tulis dan jalankan kode langsung di browser, dapatkan penilaian otomatis. Daftar gratis kapan saja untuk menyimpan progres dan meraih sertifikat.

Coba latihan sekarang, tanpa daftar
Bagikan: WhatsApp Facebook LinkedIn X