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

[NODE JS] Microtask ve Macrotask Farki

nodejs.png


[NODE JS] Microtask ve Macrotask Farki​


Merhaba arkadaslar, bugun Event Loop'un derinliklerine inmeye devam ediyoruz. Microtask ve macrotask kavramlarini anlamak, asenkron kodun calisma sirasini tahmin edebilmeniz icin sart. Bu konu is mulaklatlarinda cok sik soruluyor ve benim de kafami en cok karistiran konulardan biriydi.

Macrotask Nedir?​


Macrotask (veya sadece task), Event Loop'un ana fazlarinda islenen gorevlerdir. setTimeout, setInterval, setImmediate, I/O islemleri ve UI render (tarayicida) macrotask'tir. Her Event Loop iterasyonunda en fazla bir macrotask islenir, sonra microtask kuyrugu bosaltilir. Bu siralama cok onemlidir cunku microtask'lar her zaman macrotask'lardan once islenir.

Microtask Nedir?​


Microtask ise macrotask'lar arasinda calisan, daha oncelikli gorevlerdir. Promise.then, Promise.catch, Promise.finally, process.nextTick ve queueMicrotask microtask'tir. Microtask kuyrugu, her macrotask'tan sonra ve Event Loop fazlari arasinda tamamen bosaltilir. Yani 100 tane microtask eklerseniz, hepsi bir sonraki macrotask'tan once islenecektir.

process.nextTick aslinda teknik olarak microtask'tan bile daha oncelikli. Node.js'te nextTick kuyrugu, Promise microtask kuyrugundan once bosaltilir. Bu ince fark bazen onemli olabilir.

JavaScript:
// Microtask vs Macrotask calisma sirasi
console.log('=== Microtask vs Macrotask ===\n');

// Macrotask'lar
setTimeout(() => console.log('Macrotask 1: setTimeout'), 0);
setImmediate(() => console.log('Macrotask 2: setImmediate'));

// Microtask'lar
Promise.resolve().then(() => console.log('Microtask 1: Promise'));
process.nextTick(() => console.log('Microtask 0: nextTick (en yuksek oncelik)'));
queueMicrotask(() => console.log('Microtask 2: queueMicrotask'));

console.log('Senkron: Ana akis');

// Beklenen cikti:
// Senkron: Ana akis
// Microtask 0: nextTick
// Microtask 1: Promise
// Microtask 2: queueMicrotask
// Macrotask 1: setTimeout
// Macrotask 2: setImmediate

// Ic ice microtask'lar
console.log('\n=== Ic Ice Microtask ===');

setTimeout(() => {
    console.log('Timer 1');
}, 0);

Promise.resolve().then(() => {
    console.log('Promise 1');
    // Microtask icinden yeni microtask
    Promise.resolve().then(() => {
        console.log('Promise 2 (ic ice)');
        Promise.resolve().then(() => {
            console.log('Promise 3 (daha derin)');
        });
    });
});

setTimeout(() => {
    console.log('Timer 2');
}, 0);

// Cikti:
// Promise 1
// Promise 2 (ic ice)
// Promise 3 (daha derin)
// Timer 1
// Timer 2
// Tum microtask'lar macrotask'lardan once biter!

Neden Onemli?​


Bu kavramlari anlamak, ozellikle karmasik asenkron kodlarda hata ayiklamak icin hayati oneme sahip. Eger kodunuzun beklediginiz sirada calismadigi bir sorun yasarsaniz, buyuk ihtimalle microtask ve macrotask sirasini yanlis anlamissizdir.

Bir ornekle aciklayayim: diyelim ki bir veritabani isleminden sonra cache'i guncellemek ve log yazmak istiyorsunuz. Eger cache guncellemeyi Promise.then ile, log yazmayi setTimeout ile yaparsaniz, cache her zaman logdan once guncellenecektir. Bu davranisi bilmeden kod yazarsaniz, race condition'lara yol acabilirsiniz.

JavaScript:
// Pratik ornek: Islem sirasi garanti etme
console.log('\n=== Pratik Ornek ===');

class IslemYoneticisi {
    constructor() {
        this.islemler = [];
    }

    // Kritik islemleri microtask ile yap (hemen)
    kritikIslem(ad, fn) {
        process.nextTick(() => {
            console.log(`[KRITIK] ${ad} basladi`);
            fn();
            console.log(`[KRITIK] ${ad} bitti`);
        });
    }

    // Normal islemleri macrotask ile yap (sonra)
    normalIslem(ad, fn) {
        setImmediate(() => {
            console.log(`[NORMAL] ${ad} basladi`);
            fn();
            console.log(`[NORMAL] ${ad} bitti`);
        });
    }

    // Promise bazli islem (microtask)
    promiseIslem(ad) {
        return Promise.resolve().then(() => {
            console.log(`[PROMISE] ${ad} calisti`);
        });
    }
}

const yonetici = new IslemYoneticisi();

// Siralama testis
yonetici.normalIslem('Log yaz', () => {
    console.log('    Log kaydedildi');
});

yonetici.kritikIslem('Cache guncelle', () => {
    console.log('    Cache guncellendi');
});

yonetici.promiseIslem('Bildirim gonder');

console.log('Ana akis devam ediyor...');

// Microtask starvation ornegi - BUNU YAPMAYIN!
// function sonsuzMicrotask() {
//     process.nextTick(sonsuzMicrotask);
// }
// sonsuzMicrotask(); // Event Loop asla macrotask'a gecemez!

// Dogru yaklasim: Yogun islemleri macrotask'a dagitma
function yogunIslem(elemanlar, islemFn, grupBoyutu = 100) {
    let index = 0;

    function sonrakiGrup() {
        const bitis = Math.min(index + grupBoyutu, elemanlar.length);

        for (let i = index; i < bitis; i++) {
            islemFn(elemanlar[i]);
        }

        index = bitis;

        if (index < elemanlar.length) {
            // setImmediate ile Event Loop'a nefes aldirme
            setImmediate(sonrakiGrup);
        } else {
            console.log('\nTum elemanlar islendi!');
        }
    }

    sonrakiGrup();
}

// 1000 elemani gruplar halinde isle
const veriler = Array.from({ length: 1000 }, (_, i) => i);
yogunIslem(veriler, (eleman) => {
    // Islem simule
}, 200);

Ozet ve Tavsiyeler​


Microtask ve macrotask ayrimi Node.js'in asenkron davranisini anlamak icin temel bir bilgidir. Oncelik sirasi: senkron kod, nextTick, Promise microtask, macrotask (timer, I/O, immediate). Microtask kuyrugu macrotask'lar arasinda tamamen bosaltilir.

Benim tavsiyem: nextTick'i cok kullanmayin cunku kotu kullanim Event Loop'u aclik (starvation) durumuna dusurur. Promise'leri tercih edin, daha olusabiilr ve standart. Yogun islemleri parcalara bolup setImmediate ile dagitarak Event Loop'un nefes almasini saglayin. Ha bu arada, tarayicidaki Event Loop ile Node.js'in Event Loop'u benzer ama ayni degildir, farkli fazlar vardir. Hadi bir sonraki konuya gecelim!
 

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

Geri
Üst