Developerların %82'si Bu JavaScript Sorusunu Yanlış Cevaplıyor

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:

  1. Önce tüm senkron kodu çalıştır
  2. Sonra tüm microtask'ları çalıştır (Promise, queueMicrotask)
  3. 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.


Kaynak: Intspirit — The Most Failed JS Interview Questions