JavaScript'in asenkron yapısını kavramakta zorlanıyorum. Özellikle async/await sözdizimi ile Promise zincirlerini yönetmek ve bunun arka planda Event Loop tarafından nasıl işlendiği konusunda kafam karışıyor. Mikro görev kuyruğu, makro görev kuyruğu ve call stack'in etkileşimini örneklerle görmek istiyorum. Bu konularda temel bir anlayışa sahip olmak, daha stabil kod yazmamı sağlayacak. Siz de bu alanla ilgili öğrenme kaynakları, açıklayıcı diagramlar ya da deneyimlerinizi paylaşabilir misiniz? Birlikte keşfedelim!
JavaScript'te Async/Await Kullanımı ve Event Loop'un Çalışma Prensibi Üzerine Merakım
👁️ 32 görüntüleme💬 2 cevap❤️ 0 beğeni
2 Cevap
Async/await aslında Promise zincirlerini “kısa devre”yle çözmek için tasarlanmış bir sözdizim şekeridir; aynı iş mantığını arka planda hâlâ Promise’ler yürütür. Bunu, klasik callback‑hell ile kıyaslayınca hemen görebilirsin: callback’lerde her adımın içinde bir sonraki fonksiyon çağrısı olur ve call‑stack’in içinde derin bir iç içe yapı oluşur. Async fonksiyon ise sadece bir `Promise` döndürür ve `await` ifadesi gördüğünde, o anki fonksiyon yürütmesini durdurup kontrolü event loop’a geri verir; böylece call‑stack boşalır ve mikro görev kuyruğuna (micro‑task queue) bir “resume” işlevi eklenir. Makro görev kuyruğu (setTimeout, I/O) ise yine stack boşaldıktan sonra sıraya girer, ama micro‑task’lar her makro turdan önce tüketilir. Bu yüzden `await` sonrası bir `console.log` hemen çalışır, `setTimeout(...,0)` ise bir tur gecikir.
Pratik bir örnekle göstereyim:
```js
async function foo() {
console.log('A');
await Promise.resolve(); // micro‑task
console.log('B');
}
console.log('1');
setTimeout(() => console.log('2'), 0); // makro‑task
foo();
console.log('3');
```
Çıktı sırası **1 – A – 3 – B – 2** olur. `await`’in arkasındaki `Promise.resolve()` hemen micro‑task kuyruğuna eklenir, bu yüzden `B` yazısı, `setTimeout`’ın (makro) çalışmasından önce çıkar. Callback‑tabanlı bir kodda aynı akışı sağlamak için `setTimeout(...,0)` veya `process.nextTick` gibi ekstra “kuyruk iticileri” eklemen gerekir; async/await bu karmaşıklığı ortadan kaldırır.
Eğer bir “başka yöntem” arıyorsan, RxJS’in `from(Promise)` ve `concatMap` operatörleri de benzer bir mikro‑task davranışı sunar, fakat öğrenme eğrisi daha dik. Yeni başlayanlar için async/await + Promise zincirleri, event loop’un mikro/makro ayrımını anlamak adına en net ve sade yol. Şunu da ekleyeyim: Chrome DevTools’taki “Performance” sekmesinde “Task” ve “Microtask” işaretlerini açarsan, her adımın hangi kuyruğa düştüğünü görerek zihninde somut bir harita çizebilirsin. Valla, bu görselleştirme kodun stabilitesini artırmada çok işe yarıyor.
Async/await, Promise zincirlerini tek bir satırda toparlayıp mikro görev kuyruğuna atıyor; bu, callback çorbasını bir yudumda içiren bir çorba makinesine benzer, yani kod daha okunur ve stabil olur, kanka. Valla, setTimeout'la gelen makro görevler ise Event Loop'un bir sonraki turunda işlenir, tıpkı mikrodalga fırının bir sonraki ısıtma seansı gibi.