Ada pekerjaan yang butuh waktu, misalnya minta data ke server lewat internet. JavaScript gak berhenti menunggu: dia lanjut ke baris berikutnya, lalu baru mengurus hasilnya waktu jawabannya datang. fetch() adalah cara modern buat mengirim permintaan seperti itu (HTTP request) dari browser.
🧪 Tebakan cepat: di kode bagian pertama,
console.log('Menunggu jawaban...')ditulis paling bawah. Dia tercetak duluan atau belakangan? Tebak dulu, jawabannya ada di bagian "Minta data denganfetch".
Minta data dengan fetch
fetch('https://api.example.com/students/1')
.then((res) => {
if (!res.ok) throw new Error('HTTP ' + res.status)
return res.json()
})
.then((data) => {
console.log('Nama:', data.name)
})
.catch((err) => {
console.log('Gagal:', err.message)
})
console.log('Menunggu jawaban...')
Yang tercetak, berurutan:
Menunggu jawaban...
Nama: Budi
Baris paling bawah tercetak duluan. fetch mengirim permintaan lalu gak menunggu, jadi JavaScript langsung lanjut ke console.log('Menunggu jawaban...'). Baru waktu jawaban server datang, fungsi di dalam .then jalan.
fetch(url)langsung mengembalikan sebuah Promise: wadah buat hasil yang belum ada, kayak nomor antrean yang nanti dipanggil..then((res) => ...)jalan waktu jawaban datang.res.okbernilaitruekalau servernya menjawab sukses.res.json()membaca isi jawaban sebagai JSON. Hasilnya juga Promise, jadi di-returnke.thenberikutnya..then((data) => ...)menerima datanya, yang sudah jadi object{ name: 'Budi', age: 17 }..catch((err) => ...)jalan kalau ada yang gagal di mana pun dalam rantai itu.
fetch cuma gagal sendiri kalau jawabannya gak datang sama sekali, misalnya waktu offline. Jawaban 404 (data gak ketemu) tetap dianggap berhasil, makanya res.ok dicek lalu throw sendiri.
Bikin Promise sendiri
function cekStok(jumlah) {
return new Promise((resolve, reject) => {
if (jumlah > 0) {
resolve('Stok ada')
} else {
reject('Stok habis')
}
})
}
cekStok(3).then((hasil) => console.log(hasil)) // Stok ada
cekStok(0).catch((alasan) => console.log(alasan)) // Stok habis
new Promise(...)menerima satu fungsi, dan JavaScript memberi fungsi itu dua alat:resolvedanreject.resolve(nilai)menandai Promise berhasil. Nilainya sampai ke.then.reject(alasan)menandai Promise gagal. Alasannya sampai ke.catch.- Panggil salah satunya.
returnbiasa di dalam fungsi itu gak menyelesaikan Promise.
Promise selalu punya satu dari tiga status: pending (masih menunggu), fulfilled (berhasil, lewat resolve), atau rejected (gagal, lewat reject). Sekali selesai, statusnya gak berubah lagi.
Promise yang selesai sesudah jeda
setTimeout(fungsi, ms) menjadwalkan fungsi buat jalan sesudah sekian milidetik. Panggil resolve di dalam jadwal itu, maka Promise-nya baru selesai sesudah jeda:
function tungguLalu(pesan) {
return new Promise((resolve) => {
setTimeout(() => {
resolve('Pesan: ' + pesan)
}, 500)
})
}
tungguLalu('siap').then((hasil) => console.log(hasil))
console.log('Mulai')
Yang tercetak Mulai dulu, setengah detik kemudian Pesan: siap. Kalau resolve ditulis di luar setTimeout, Promise-nya selesai seketika tanpa jeda.
⚠️ Jebakan yang sering ketemu
- Mengira
fetchlangsung memberi data.const data = fetch(url)isinya Promise, bukan data. Ambil datanya di.then, atau pakaiawaitdi materi berikutnya. - Gak ada
.catch. Kalau Promise gagal tanpa.catch, console menampilkan "Uncaught (in promise)" dan pengguna gak dapat pesan apa pun. - Lupa cek
res.ok. Tanpa cek itu, jawaban404ikut diproses seolah datanya ada.
TL;DR: Kode sesudah fetch jalan duluan, hasilnya diurus belakangan di .then. fetch(url) mengembalikan Promise: .then buat hasil, .catch buat kegagalan, dan cek res.ok karena 404 gak dianggap gagal. Bikin Promise sendiri dengan new Promise((resolve, reject) => ...): resolve(nilai) buat berhasil, reject(alasan) buat gagal. Statusnya pending, lalu fulfilled atau rejected.