mannaxxx 1
mannaxxx
Agora Metin2 1
Agora Metin2
[DEV]AB 1
[DEV]AB
Sevdamsın 1
Sevdamsın
TuZaKK 1
TuZaKK
kaptanmikro1 1
kaptanmikro1
farkmt2official 2
farkmt2official
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
Bvural41 1
Bvural41
Hikaye Ekle

[NODE JS] EventEmitter ile Olay Tabanli Programlama

Türkiye'de ilk Mobil & PC Aynı Anda Metin2 Oyna. Triarchonline kalıcı ve uzun ömürlü yapısı ile 24 Temmuz'da açılıyor. | 1-99 Mobil Metin2 Triarch HEMEN TIKLA!

nodejs.png


[NODE JS] EventEmitter ile Olay Tabanli Programlama​


Merhaba arkadaslar, bugun Node.js'in en temel yapilarindan biri olan EventEmitter'i inceleyecegiz. Node.js'te neredeyse her sey event tabanlidir: HTTP sunucusu bir istek geldiginde event atar, stream veri geldiginde event atar, dosya islemleri bittiginde event atar. Bu yapiyi anlamak Node.js'i anlamaktir desem yanlis olmaz.

EventEmitter Temelleri​


EventEmitter, Node.js'in events modulunde bulunan bir siniftir. Temel mantigi basittir: bir nesne olay yayinlar (emit), diger kodlar bu olaylari dinler (on/addListener). Bu, Observer design pattern'inin bir implementasyonudur. Ben bu pattern'i cok seviyorum cunku kodunuzu gevsk bagli (loosely coupled) yapar.

Bir EventEmitter kullanmanin avantaji, bilesenlerin birbirini dogrudan tanimak zorunda olmamasidir. Bir bilesen olay yayinlar, diger bilesenler dinler. Yayinlayan kimin dinledigini bilmez, dinleyen kimin yayinladigini umursamaz. Bu sayede modüler ve genisletilebilir kod yazabilirsiniz.

JavaScript:
const EventEmitter = require('events');

// Temel EventEmitter kullanimi
const emitter = new EventEmitter();

// Olay dinleyici ekle
emitter.on('selam', (isim) => {
    console.log(`Merhaba ${isim}!`);
});

emitter.on('selam', (isim) => {
    console.log(`Hosgeldin ${isim}!`);
});

// Olay yayinla
emitter.emit('selam', 'Ahmet');
// Her iki dinleyici de tetiklenir

// Birden fazla parametre
emitter.on('siparis', (urun, miktar, fiyat) => {
    console.log(`\nSiparis: ${miktar}x ${urun} = ${miktar * fiyat} TL`);
});

emitter.emit('siparis', 'Laptop', 2, 15000);

// once: Sadece bir kez dinle
emitter.once('baslat', () => {
    console.log('\nUygulama baslatildi (bu sadece 1 kez calisir)');
});

emitter.emit('baslat'); // Calisir
emitter.emit('baslat'); // Calismaz!

// Dinleyici sayisi
console.log('\nselam dinleyici sayisi:', emitter.listenerCount('selam'));

// Dinleyici kaldir
function logHandler(mesaj) {
    console.log('LOG:', mesaj);
}

emitter.on('log', logHandler);
emitter.emit('log', 'Test mesaji');

emitter.removeListener('log', logHandler);
emitter.emit('log', 'Bu gorulmeyecek');

Gercek Hayat Ornegi: Siparis Sistemi​


Simdi EventEmitter'i gercek bir uygulamada nasil kullanacagimizi gorelim. Bir siparis sistemi dusunun: siparis olusturuldugunda farkli islemler yapilmasi gerekiyor: stok guncelleme, fatura olusturma, bildirim gonderme, log kaydi. Tum bu islemleri siparis fonksiyonunun icine yazmak yerine, event'ler uzerinden iletisim kurabiliriz.

JavaScript:
const EventEmitter = require('events');

class SiparisSistemi extends EventEmitter {
    constructor() {
        super();
        this.siparisler = [];
    }

    siparisOlustur(siparisBilgi) {
        const siparis = {
            id: 'SIP-' + Date.now(),
            ...siparisBilgi,
            tarih: new Date().toISOString(),
            durum: 'olusturuldu'
        };

        this.siparisler.push(siparis);

        // Olaylari yayinla - dinleyiciler gerisini halleder
        this.emit('siparis:olusturuldu', siparis);

        return siparis;
    }

    siparisIptal(siparisId) {
        const siparis = this.siparisler.find(s => s.id === siparisId);
        if (!siparis) {
            this.emit('siparis:hata', new Error(`Siparis bulunamadi: ${siparisId}`));
            return;
        }

        siparis.durum = 'iptal';
        this.emit('siparis:iptal', siparis);
    }

    siparisTamamla(siparisId) {
        const siparis = this.siparisler.find(s => s.id === siparisId);
        if (siparis) {
            siparis.durum = 'tamamlandi';
            this.emit('siparis:tamamlandi', siparis);
        }
    }
}

// Siparis sistemini kur
const sistem = new SiparisSistemi();

// Stok yonetici modulu
sistem.on('siparis:olusturuldu', (siparis) => {
    console.log(`[Stok] ${siparis.urunAdi} stoktan dusuruluyor...`);
});

sistem.on('siparis:iptal', (siparis) => {
    console.log(`[Stok] ${siparis.urunAdi} stoga geri ekleniyor...`);
});

// Bildirim modulu
sistem.on('siparis:olusturuldu', (siparis) => {
    console.log(`[Bildirim] "${siparis.kullanici}" kullanicisina onay maili gonderiliyor...`);
});

sistem.on('siparis:tamamlandi', (siparis) => {
    console.log(`[Bildirim] "${siparis.kullanici}" kullanicisina teslim bildirimi gonderiliyor...`);
});

// Log modulu
sistem.on('siparis:olusturuldu', (siparis) => {
    console.log(`[Log] Yeni siparis: ${siparis.id}`);
});

sistem.on('siparis:iptal', (siparis) => {
    console.log(`[Log] Iptal: ${siparis.id}`);
});

sistem.on('siparis:hata', (error) => {
    console.error(`[Log] HATA: ${error.message}`);
});

// Siparis islemleri
console.log('=== Siparis Sistemi ===\n');

const siparis1 = sistem.siparisOlustur({
    kullanici: 'Ahmet',
    urunAdi: 'Laptop',
    tutar: 15000
});

console.log('');
sistem.siparisTamamla(siparis1.id);

console.log('');
sistem.siparisIptal('SIP-999');

Hata Yonetimi ve En Iyi Pratikler​


EventEmitter'da onemli bir kural var: 'error' event'i ozel bir event'tir. Eger 'error' event'ini dinleyen hicbir listener yoksa ve bir error event'i emit edilirse, Node.js bir exception firlatir ve process crash eder. Bu yuzden her zaman error event'ini dinleyin. Ayrica listener sayisi varsayilan olarak 10 ile sinirlidir. Bunu asmak icin setMaxListeners kullanabilirsiniz ama cogu zaman 10'dan fazla listener ihtiyaci bir tasarim sorununa isaret eder.

Tecrubeme gore EventEmitter'i dogru kullanmak icin su kurallari takip edin: event isimlerini tutarli bir sekilde adlandirin (namespace kullanin), listener'lari temizlemeyi unutmayin (memory leak), error event'ini her zaman dinleyin ve cok fazla event kullanmayin. Event tabanli programlama gucludur ama asiri kullanim kodunuzu takip edilmesi zor hale getirebilir. Sonraki konuda kendi EventEmitter sinifimizi yazacagiz!
 

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

Benzer konular

Geri
Üst