Timer bikin kode jalan nanti, bukan sekarang. setTimeout menjalankan sebuah fungsi sekali setelah jeda tertentu, setInterval menjalankannya berulang-ulang dengan jeda yang sama. Jedanya ditulis dalam milidetik (ms): 1000 ms = 1 detik.
🧪 Tebakan cepat:
setTimeout(fn, 0)artinya jedanya nol. Apakahfnlangsung jalan sebelum baris sesudahnya? Tebak dulu, jawabannya ada di bagian "Kode setelah timer gak ikut menunggu".
Menjadwalkan kode dengan setTimeout
console.log('Mulai')
const id = setTimeout(() => {
console.log('Selesai!')
}, 2000)
console.log('Menunggu...')
setTimeout(fungsi, jeda)menerima dua hal: fungsi yang dijalankan nanti, dan jedanya dalam milidetik.() => { ... }adalah fungsi itu. Fungsi yang dititipkan buat dipanggil belakangan disebut callback. Isinya belum jalan, cuma dijadwalkan.2000artinya 2 detik. Bukan2: itu cuma 2 milidetik.const id = ...menyimpan nomor timer yang dikembalikansetTimeout. Nomor ini dipakai buat membatalkannya.
Hasil di console: Mulai, Menunggu..., lalu 2 detik kemudian Selesai!.
Kode setelah timer gak ikut menunggu
setTimeout cuma menjadwalkan callback, lalu JavaScript langsung lanjut ke baris berikutnya. Makanya Menunggu... muncul sebelum Selesai!. Ini tetap berlaku walau jedanya 0:
console.log('A')
setTimeout(() => console.log('B'), 0)
console.log('C')
Yang tercetak A, C, lalu B. Jadi yang dicetak pertama tetap A. Jeda 0 artinya "secepatnya setelah kode yang sedang jalan selesai", bukan "sekarang juga". Callback-nya antre dulu, dan baru dapat giliran setelah semua kode biasa habis.
Mengulang dengan setInterval, berhenti dengan clearInterval
let detik = 0
const id = setInterval(() => {
detik++
console.log(`Detik ke-${detik}`)
if (detik === 3) {
clearInterval(id)
console.log('Berhenti!')
}
}, 1000)
setInterval(fungsi, jeda)menjalankan callback tiapjedamilidetik, terus-terusan.- Dia juga mengembalikan id. Simpan di
const id. clearInterval(id)menghentikan interval itu. Tanpa id, gak ada cara buat menghentikannya.
Hasilnya Detik ke-1, Detik ke-2, Detik ke-3, lalu Berhenti!, satu baris tiap detik. Timeout juga bisa dibatalkan sebelum sempat jalan, pakai clearTimeout(id). Dengan const id = setTimeout(...) lalu clearTimeout(id), callback-nya gak pernah jalan.
Menunggu lewat Promise
setTimeout gak mengembalikan hasil callback-nya, cuma id. Kalau kamu butuh fungsi yang "selesai nanti, sambil membawa nilai", bungkus timer-nya dengan Promise:
function tunggu(ms, nilai) {
return new Promise((resolve) => {
setTimeout(() => resolve(nilai), ms)
})
}
tunggu(1000, 'Siap').then((hasil) => console.log(hasil))
return new Promise(...)bikin fungsinya langsung mengembalikan janji, bukan nilainya.resolveadalah tombol "selesai" milik Promise itu. Nilai yang dikirim keresolve(...)jadi hasil janjinya.resolve(nilai)dipanggil di dalam callbacksetTimeout, jadi janjinya baru selesai setelahmsmilidetik lewat.
Setelah 1 detik, console mencetak Siap. Di dalam fungsi async bisa juga ditulis const hasil = await tunggu(1000, 'Siap').
Hitung mundur jadi array
setInterval menampilkan angka satu per satu. Kalau yang kamu butuhkan cuma daftar angkanya sekaligus, pakai loop for yang turun:
const angka = []
for (let i = 3; i >= 0; i--) {
angka.push(i)
}
console.log(angka) // [3, 2, 1, 0]
let i = 3 mulai dari angka teratas, i >= 0 bikin 0 ikut masuk (dengan i > 0, angka 0 ketinggalan), dan i-- mengurangi 1 tiap putaran.
⚠️ Jebakan yang sering ketemu
- Gak menyimpan id.
setInterval(...)tanpaconst id =gak bisa dihentikan, dan terus jalan walau sudah gak dibutuhkan. - Menulis
setTimeout(sapa(), 1000). Tanda kurung bikinsapalangsung jalan sekarang. TulissetTimeout(sapa, 1000)atausetTimeout(() => sapa(), 1000). resolvedipanggil di luar callback. Janjinya langsung selesai, tanpa menunggu jeda.- Mengira jedanya tepat. Jeda adalah waktu minimal. Kalau browser sedang sibuk, callback-nya bisa telat sedikit.
TL;DR: setTimeout(fn, ms) menjalankan fn sekali setelah ms milidetik, setInterval(fn, ms) menjalankannya tiap ms milidetik. Dua-duanya mengembalikan id, dan clearTimeout(id) atau clearInterval(id) menghentikannya. Kode setelah timer gak ikut menunggu, bahkan dengan jeda 0. Butuh nilai setelah jeda? Panggil resolve(nilai) di dalam setTimeout, di dalam new Promise.