Node.js'de Microtask Queues ve Çalışma Sırası
admin

Node.js, asenkron yapısıyla bilinen ve büyük ölçekli uygulamalarda verimlilik sağlayan popüler bir JavaScript çalışma zamanı ortamıdır. Bu yazıda, Node.js'in mikro görev kuyrukları ve bunların çalışma sırasını detaylı bir şekilde inceleyeceğiz. Mikro görev kuyruklarının nasıl çalıştığını anlamak, Node.js uygulamalarının performansını optimize etmek için kritik öneme sahiptir.
Node.js Event Loop Yapısı:
Node.js event loop, farklı türde görevlerin yürütüldüğü altı ana kuyruktan oluşur:
- Next Queue: process.nextTick tarafından oluşturulan görevlerin saklandığı kuyruk.
- Promise Queue: Promise.resolve().then ile oluşturulan görevlerin saklandığı kuyruk.
- Timer Queue: setTimeout ve setInterval gibi zamanlayıcı fonksiyonları tarafından oluşturulan görevlerin saklandığı kuyruk.
- Input-Output (I/O) Queue: I/O işlemleri için kullanılan kuyruk.
- Check Queue: setImmediate tarafından oluşturulan görevlerin saklandığı kuyruk.
- Close Queue: close event'lerinin işlenmesi için kullanılan kuyruk.
Bu kuyruklar, event loop içerisinde belirli bir sırayla işlenir ve her biri farklı türde görevleri işler.
Visualizing the event loopMikro Görev Kuyrukları:
Mikro görev kuyrukları, next queue ve promise queue olarak ikiye ayrılır. Bu kuyruklar, event loop'un belirli aşamalarında öncelikli olarak işlenir. Mikro görev kuyrukları, özellikle yüksek öncelikli küçük görevlerin hızlı bir şekilde işlenmesi için kullanılır.
Process.nextTick ve Promise.resolve:
-
process.nextTick: Bu yöntem, bir callback fonksiyonunu next tick kuyruğuna ekler.
process.nextTick, event loop'un bir sonraki aşamasına geçmeden önce çalıştırılacak küçük görevleri tanımlamak için kullanılır.-
Kullanımı:
process.nextTick(callbackFonksiyonu)- Promise.resolve().then: Bu yöntem, bir callback fonksiyonunu promise kuyruğuna ekler. Promise.resolve().then, Promise'ların tamamlanmasının ardından çalıştırılacak görevleri tanımlar.
-
Kullanımı:
Promise.resolve().then(callbackFonksiyonu)
-
Örnekler ve Çıkarımlar:
-
İlk Örnek:
İlk örnekte, iki
console.logifadesi ve aralarına birprocess.nextTickifadesi eklenir. Kod şu şekildedir:console.log(1); process.nextTick(() => { console.log('This is process.nextTick callback'); }); console.log(2);Sonuç: İlk olarak senkron
console.logifadeleri çalıştırılır ve ardındanprocess.nextTickiçindeki callback fonksiyonu çalıştırılır. Bu durum, senkron JavaScript kodunun, asenkron koddan önce çalıştığını gösterir. Yani,process.nextTickfonksiyonu, çağrı yığını tamamen boşaldıktan sonra çalışır.- İkinci Örnek:
İkinci örnekte,
process.nextTickvePromise.resolve().thenifadeleri birlikte kullanılır:Promise.resolve().then(() => { console.log('This is Promise.resolve callback'); }); process.nextTick(() => { console.log('This is process.nextTick callback'); });Sonuç:
process.nextTickiçindeki callback fonksiyonları, promise kuyruğundakilerden önce çalışır. Yani, next tick kuyruğundaki tüm callback'ler, promise kuyruğundakilerden önceliklidir.- Gelişmiş Örnek:
İç içe
process.nextTickvePromise.resolve().thenifadeleri kullanılarak daha karmaşık bir yapı oluşturulur. Kod şu şekildedir:process.nextTick(() => console.log("process.nextTick 1")); process.nextTick(() => { console.log("process.nextTick 2"); process.nextTick(() => console.log("next tick içinde iç next tick") ); }); process.nextTick(() => console.log("process.nextTick 3")); Promise.resolve().then(() => console.log("Promise.resolve 1")); Promise.resolve().then(() => { console.log("Promise.resolve 2"); process.nextTick(() => console.log("Promise then bloğu içinde iç next tick") ); }); Promise.resolve().then(() => console.log("Promise.resolve 3"));Sonuç: İlk olarak,
process.nextTickiçindeki callback fonksiyonları çalıştırılır. İç içe olanprocess.nextTickfonksiyonları, dıştakiler tamamlanana kadar çalıştırılmaz. Sonrasında,Promise.resolve().theniçindeki callback fonksiyonları çalıştırılır. Bu durum, next tick kuyruğunun promise kuyruğuna göre öncelikli olduğunu bir kez daha doğrular.
microtask queue
Önemli Notlar:
process.nextTick'in aşırı kullanımı, event loop’un diğer bölümlerinin çalışmasını engelleyebilir. Bu, I/O kuyruğunun çalışmasını engelleyerek performans sorunlarına yol açabilir. process.nextTick, iki ana amaç için kullanılmalıdır:
- Kullanıcıların hataları işlemesine, gereksiz kaynakları temizlemesine veya isteği yeniden denemesine izin vermek.
- Çağrı yığını çözüldükten ancak event loop devam etmeden önce bir callback çalıştırmak.
Sonuç:
Node.js'te mikro görev kuyrukları ve bunların çalışma sırasını anlamak, performansı optimize etmek ve daha verimli asenkron kod yazmak için kritik öneme sahiptir. process.nextTick ve Promise.resolve().then gibi yöntemlerin nasıl çalıştığını ve event loop içerisinde nasıl önceliklendirildiklerini bilmek, geliştiricilerin daha etkili Node.js uygulamaları yazmalarına yardımcı olur. Bu bilgiler, Node.js'in asenkron doğasını daha iyi kavramak ve uygulamalarınızda daha verimli çözümler üretmek için temel oluşturur.






