Developerların %82'si Bu JavaScript Sorusunu Yanlış Cevaplıyor
Intspirit'in binlerce developer üzerinde yaptığı ankete göre, bu soruyu sadece %18'i doğru biliyor. Soru basit görünüyor ama cevabı çoğu kişiyi şaşırtıyor.
Soru
setTimeout(() => console.log(1), 0);
Promise.resolve()
.then(() => console.log(2));
console.log(3);
Çıktısı ne?
- A) 1, 2, 3
- B) 3, 1, 2
- C) 3, 2, 1
- D) 2, 3, 1
Düşün, cevabını belirle, sonra okumaya devam et.
Cevap: C — 3, 2, 1
Çoğu kişi setTimeout(fn, 0) görünce "0 milisaniye, yani hemen çalışır" diye düşünüyor. Ama öyle değil. Neden mi?
JavaScript tek thread üzerinde çalışır. Aynı anda sadece bir iş yapabilir. Async işlemleri yönetmek için Event Loop denen bir mekanizma var. Ve bu mekanizmanın basit bir kuralı var:
Senkron kod → Microtask → Macrotask
Bu üç kavramı anlaman yeterli:
- Call Stack: Senkron kod burada çalışır.
console.log(3)gibi. - Microtask Queue: Promise callback'leri burada bekler. Önceliği yüksek.
- Macrotask Queue: setTimeout callback'leri burada bekler. En son çalışır.
Adım Adım Ne Oluyor?
Adım 1 — setTimeout çalışır
setTimeout(() => console.log(1), 0);
Motor bu satırı okur. Callback fonksiyonunu Web API'ye gönderir. 0ms sonra bu callback Macrotask Queue'ya eklenir.
Call Stack'te artık bu satır yok. Devam ediyor.
Adım 2 — Promise.resolve().then() çalışır
Promise.resolve()
.then(() => console.log(2));
Promise zaten resolved durumda. .then() içindeki callback doğrudan Microtask Queue'ya eklenir.
Call Stack'te bu da bitti. Devam ediyor.
Adım 3 — console.log(3) çalışır
console.log(3);
Bu senkron kod. Hemen çalışır.
Konsol: 3
Adım 4 — Call Stack boşaldı, Event Loop devreye giriyor
Event Loop önce Microtask Queue'ya bakar. Orada Promise callback'i var. Onu çalıştırır.
Konsol: 3, 2
Adım 5 — Microtask bitti, sıra Macrotask'ta
Microtask Queue boş. Şimdi Macrotask Queue'ya bakılır. setTimeout callback'i çalışır.
Konsol: 3, 2, 1
Neden setTimeout(fn, 0) Hemen Çalışmıyor?
0ms demek "mümkün olan en kısa sürede" demek, "hemen şimdi" demek değil.
setTimeout callback'i her zaman Macrotask Queue'ya gider. Ve Event Loop'un kuralı net:
- Önce tüm senkron kodu çalıştır
- Sonra tüm microtask'ları çalıştır (Promise, queueMicrotask)
- En son bir macrotask çalıştır (setTimeout, setInterval)
Bu yüzden 0ms bile olsa, Promise'den sonra çalışır.
Özet
Öncelik sırası:
Senkron kod → console.log(3) → ilk çalışır
Microtask → Promise.then() → ikinci çalışır
Macrotask → setTimeout() → en son çalışır
Bu kuralı bir kere öğrendiğinde, event loop sorularında bir daha takılmazsın.