farkmt2official 1
farkmt2official
mannaxxx 1
mannaxxx
Bvural41 1
Bvural41
Agora Metin2 1
Agora Metin2
berkmenoo 1
berkmenoo
Hikaye Ekle

[NODE JS] Event Loop Nasil Calisir?

nodejs.png


[NODE JS] Event Loop Nasil Calisir?​


Merhaba arkadaslar, bugun Node.js'in kalbini olusturan Event Loop mekanizmasini derinlemesine inceleyecegiz. Eger Node.js'i gercekten anlamak istiyorsaniz, Event Loop'u anlamalisiniz. Bu konu is mulaklatlarinda en sik sorulan konulardan biri ve ben de ilk mulakatimda bu soruyu yanlis cevaplamistim. O gunden sonra Event Loop'u iyice oturana kadar calistim.

Event Loop Nedir?​


Event Loop, Node.js'in tek bir thread uzerinde asenkron islemleri yonetmesini saglayan mekanizmadir. Node.js tek threaded'dir ama IO islemlerini bloklamaz. Peki bunu nasil basariyor? Islemleri isletim sistemine veya libuv'un thread pool'una devrediyor ve islem bittiginde sonucu Event Loop uzerinden geri aliyor.

Bunu bir restoranin garsonu gibi dusunun. Garson tek kisi ama birden fazla masaya hizmet veriyor. Bir masanin siparisini alip mutfaga verdikten sonra, yemek hazirlanana kadar bos durmuyor, diger masalara gidiyor. Yemek hazir oldugunda mutfaktan sinyal geliyor ve garson yemegi masaya goturuyor. Garson Event Loop, mutfak ise libuv thread pool'u.

Event Loop Fazlari​


Event Loop bes ana fazdan oluşur ve her faz belirli turlerdeki callback'leri isler. Dongu surekli bu fazlar arasinda doner ve islenecek callback varsa isler, yoksa bir sonraki faza gecer.

JavaScript:
// Event Loop fazlarini gormek icin ornek
const fs = require('fs');

console.log('=== Event Loop Fazlari ===\n');

// 1. TIMERS FAZI: setTimeout ve setInterval callback'leri
setTimeout(() => {
    console.log('[Timers] setTimeout callback');
}, 0);

// 2. I/O CALLBACKS FAZI: Sistem islemleri callback'leri
fs.readFile(__filename, () => {
    console.log('[I/O] Dosya okuma callback');

    // I/O callback icinde setTimeout
    setTimeout(() => {
        console.log('[Timers] I/O icindeki setTimeout');
    }, 0);

    // I/O callback icinde setImmediate
    setImmediate(() => {
        console.log('[Check] I/O icindeki setImmediate');
    });

    // I/O callback icinde nextTick
    process.nextTick(() => {
        console.log('[Microtask] I/O icindeki nextTick');
    });
});

// 3. IDLE/PREPARE FAZI: Dahili kullanim (dogrudan erisilemez)

// 4. POLL FAZI: Yeni I/O event'lerini bekler
// (Bu faz otomatik calisir, dogrudan tetikleyemeyiz)

// 5. CHECK FAZI: setImmediate callback'leri
setImmediate(() => {
    console.log('[Check] setImmediate callback');
});

// 6. CLOSE CALLBACKS FAZI: socket.on('close') gibi
// (ornek icin uygun degil)

// Microtask kuyrugu (fazlar arasi calisir)
process.nextTick(() => {
    console.log('[Microtask] nextTick callback');
});

Promise.resolve().then(() => {
    console.log('[Microtask] Promise.then callback');
});

console.log('[Senkron] Ana modul sonu');

Senkron vs Asenkron Calisma Sirasi​


Event Loop'un calisma sirasini anlamak icin su kurallari bilin: Once tum senkron kod calisir. Sonra microtask kuyrugu bosaltilir (nextTick ve Promise). Sonra Event Loop fazlari sirayla calisir ve her faz arasinda microtask kuyrugu tekrar bosaltilir. Bu bilgi ozellikle performans optimizasyonu ve hata ayiklama icin cok degerlidir.

JavaScript:
// Event Loop calisma sirasini gosteren detayli ornek
console.log('=== Calisma Sirasi Analizi ===\n');

// Senkron islemler - HER ZAMAN ONCE
console.log('1. Senkron: Baslangic');

// setTimeout - Timers fazinda calisir
setTimeout(() => {
    console.log('5. Timer: setTimeout 0ms');

    Promise.resolve().then(() => {
        console.log('6. Microtask: Timer icindeki Promise');
    });

    process.nextTick(() => {
        console.log('7. NextTick: Timer icindeki nextTick');
        // Not: nextTick Promise'den once calisir!
    });
}, 0);

// setImmediate - Check fazinda calisir
setImmediate(() => {
    console.log('8. Immediate: setImmediate');
});

// Promise - Microtask kuyruqu (fazlar arasinda)
Promise.resolve().then(() => {
    console.log('3. Microtask: Promise.then');
});

// process.nextTick - Microtask kuyrugu (Promise'den once!)
process.nextTick(() => {
    console.log('2. NextTick: process.nextTick');
});

// Bir Promise daha
Promise.resolve().then(() => {
    console.log('4. Microtask: Ikinci Promise');
});

console.log('1b. Senkron: Bitis');

// Beklenen sira:
// 1. Senkron: Baslangic
// 1b. Senkron: Bitis
// 2. NextTick: process.nextTick
// 3. Microtask: Promise.then
// 4. Microtask: Ikinci Promise
// 5. Timer: setTimeout 0ms
// (nextTick ve Promise sirasi burada farkli olabilir)
// 8. Immediate: setImmediate

Event Loop Bloklanmasi​


Event Loop'un en buyuk dusmani CPU-yogun islemlerdir. Eger senkron bir dongu icinde milyon tane islem yaparsaniz, Event Loop bloklanir ve uygulamaniz donuk kalir. Buna "blocking the event loop" denir ve bu Node.js'in bir numarali performans sorunudur.

Ben bir keresinde bir API endpoint'inde buyuk bir JSON dosyasini parse ederken sunucunun donmasina neden olmustum. 50 MB'lik bir JSON dosyasini JSON.parse ile senkron olarak parse etmek Event Loop'u saniyeler boyunca blokladı ve o sırada gelen tum istekler askida kaldi. Cozumu stream bazli JSON parser kullanmak oldu.

Tecrubeme gore su islemler Event Loop'u bloklar: buyuk dosyalari senkron okuma/yazma, karmasik regex pattern'leri, buyuk dizilerde senkron siralama/filtreleme, agir kriptografik islemler ve buyuk JSON parse/stringify. Bu islemleri ya Worker Threads'e devredin ya da async alternatifleri kullanin. Event Loop'u bloklamak en buyuk gunah sayilir Node.js dunyasinda. Siradaki konumuz microtask ve macrotask farki, o da bununla cok iliskili!
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst