setTimeout & setInterval — JavaScript

Pernah liat banner promo yang muncul 5 detik setelah kamu masuk website? Atau notifikasi "Live: 23 orang lagi liat produk ini" yang update tiap detik? Itu…

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. Apakah fn langsung 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...')

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)

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))

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

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.

Yang akan kamu pelajari