---
title: 'Olay Yayıcı'
source: 'https://academia.sh/tr/kurslar/nodejs/olay-yayici'
course: 'Node.js Çalışma Zamanı'
language: tr
updated: '2026-08-17T18:09:51+00:00'
license: 'CC BY-SA 4.0'
---

# Olay Yayıcı

Gözlemci kalıbının yerleşik gerçekleştirimi, yayımın eşzamanlılığı, hata olayının ayrıcalıklı davranışı, dinleyici sınırı uyarısı ve olayların söz biçimiyle beklenmesi.

Akış dersinde geçen `data`, `end` ve `drain` adları tek bir düzenekten gelir. Aynı
düzenek HTTP sunucusunda, alt süreçlerde ve süreç nesnesinin sinyal bildirimlerinde
de kullanılır: çalışma zamanının eşzamansız arayüzlerinin çoğu bu tek sınıfın
üstüne kurulmuştur.

Bu ders o sınıfı ele alır ve ölçüm toplayıcının veri kaynağını olay tabanlı hâle
getirir: kayıt geldiğinde haber veren, eşik aşıldığında uyaran, bozuk satırı
bildiren bir kaynak.

## Gözlemci Kalıbının Yerleşik Gerçekleştirimi

`node:events` modülündeki `EventEmitter` sınıfı, ad başına dinleyici listesi tutar.
`on` ile listeye eklenir, `emit` ile liste sırayla çağrılır. Bu, Programlama
Temelleri kursundaki yüksek mertebeden fonksiyon kavramının doğrudan uygulamasıdır:
davranış, bir değer olarak saklanır ve zamanı gelince çağrılır.

Kalıbın kazancı, üretici ile tüketici arasındaki bağı gevşetmesidir. Kaynak, kimin
dinlediğini bilmez; dinleyici, kaynağın iç işleyişini bilmez. Aralarındaki tek
sözleşme olay adı ve yükün biçimidir.

```js
// yayici.mjs
import { EventEmitter } from 'node:events';

class OlcumKaynagi extends EventEmitter {
  besle(satir) {
    try {
      const kayit = JSON.parse(satir);
      this.emit('olcum', kayit);
      if (kayit.metrik === 'sicaklik' && kayit.deger > 24) {
        this.emit('esik-asildi', kayit);
      }
    } catch (hata) {
      this.emit('hata-satiri', { satir, hata });
    }
  }
}

const kaynak = new OlcumKaynagi();

kaynak.on('olcum', (k) => console.log('olcum      :', k.dugum, k.metrik, k.deger));
kaynak.once('esik-asildi', (k) => console.log('esik (bir kez):', k.dugum, k.deger));
kaynak.on('hata-satiri', ({ satir }) => console.log('bozuk satir:', satir));

kaynak.besle('{"dugum":"kenar-01","metrik":"sicaklik","deger":21.4}');
kaynak.besle('{"dugum":"kenar-03","metrik":"sicaklik","deger":24.1}');
kaynak.besle('{"dugum":"kenar-03","metrik":"sicaklik","deger":24.6}');
kaynak.besle('bozuk');

console.log('olcum dinleyici sayisi:', kaynak.listenerCount('olcum'));
console.log('esik dinleyici sayisi :', kaynak.listenerCount('esik-asildi'));
```

```sh
node yayici.mjs
```

```
olcum      : kenar-01 sicaklik 21.4
olcum      : kenar-03 sicaklik 24.1
esik (bir kez): kenar-03 24.1
olcum      : kenar-03 sicaklik 24.6
bozuk satir: bozuk
olcum dinleyici sayisi: 1
esik dinleyici sayisi : 0
```

`once` ile eklenen dinleyici ilk yayımdan sonra listeden çıkarılır; çıktının son
satırındaki sıfır bunu doğruluyor. İkinci eşik aşımında uyarı yazılmamış olması da
aynı nedenledir. Kalıcı dinleyici için `on`, tek seferlik olan için `once` kullanılır;
elle kaldırmak gerektiğinde `off` çağrısına dinleyicinin **aynı referansı** verilmelidir
— adsız bir fonksiyon ifadesiyle eklenen dinleyici bir daha kaldırılamaz.

## Yayım Eşzamanlıdır

Ad "olay" olduğu için bir kuyruğa girdiği sanılabilir. Öyle değildir: `emit`,
dinleyicileri eklenme sırasına göre **o anda** çağırır ve hepsi bitince döner.

```js
// yayici-senkron.mjs
import { EventEmitter } from 'node:events';
const y = new EventEmitter();
y.on('olay', () => console.log('2 dinleyici'));
console.log('1 emit oncesi');
y.emit('olay');
console.log('3 emit sonrasi');
```

```sh
node yayici-senkron.mjs
```

```
1 emit oncesi
2 dinleyici
3 emit sonrasi
```

Bunun iki sonucu vardır. Birincisi, dinleyici içinde yapılan uzun senkron iş, olay
döngüsünü diğer her şey gibi durdurur; olay yaymak işi ertelemez. İkincisi, dinleyici
içinde fırlatılan bir hata `emit` çağrısının yapıldığı yere doğru yayılır — kaynak
kodunun ortasına, hiç beklemediği bir yere.

Bir dinleyicinin işini erteleyerek çağıranı serbest bırakması gerekiyorsa erteleme
açıkça yazılır: iş bir zamanlayıcıya veya mikro göreve bırakılır. Kaynağın kendisi bu
kararı veremez.

## Hata Olayının Ayrıcalığı

`error` adı, sınıf içinde özel olarak ele alınır. Bu ada dinleyici yokken yayım
yapılırsa, yük fırlatılır ve yakalanmazsa süreç sonlanır.

```js
// yayici-hata.mjs
import { EventEmitter } from 'node:events';

const dinleyicili = new EventEmitter();
dinleyicili.on('error', (h) => console.log('yakalandi:', h.message));
dinleyicili.emit('error', new Error('kaynak kapandi'));

const dinleyicisiz = new EventEmitter();
dinleyicisiz.emit('error', new Error('bu firlatilacak'));
console.log('bu satira ulasilmaz');
```

Standart çıktıya yalnızca tek bir satır düşer:

```sh
node yayici-hata.mjs 2>/dev/null
```

```
yakalandi: kaynak kapandi
```

Süreç ikinci yayımda sonlanır; `bu satira ulasilmaz` satırı yazılmaz ve standart
hataya bir yığıt izi düşer. İzin içeriği dosya yollarını taşıdığı için makineye göre
değişir.

Bu davranış bilinçli bir tasarımdır. Eşzamansız bir kaynağın hatası sessizce
yutulursa, program yanlış veriyle çalışmaya devam eder ve arıza çok sonra, ilgisiz
bir yerde görünür. Kural şudur: **hata yayabilen her nesneye bir `error` dinleyicisi
takılır.** Akış nesneleri de birer olay yayıcı olduğundan bu kural onlar için de
geçerlidir; önceki derste `pipeline` kullanmanın gerekçelerinden biri, bu dinleyiciyi
zincirdeki her akış için kendiliğinden kurmasıdır.

## Dinleyici Sınırı

Bir ada eklenen dinleyici sayısı varsayılan sınırı aştığında çalışma zamanı bir uyarı
yazar:

```js
// yayici-sinir.mjs
import { EventEmitter } from 'node:events';
const y = new EventEmitter();
for (let i = 0; i < 11; i += 1) y.on('olcum', () => {});
console.log('dinleyici sayisi:', y.listenerCount('olcum'));
```

```sh
node yayici-sinir.mjs
```

```
dinleyici sayisi: 11
(node:59045) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 olcum listeners added to [EventEmitter]. MaxListeners is 10. Use emitter.setMaxListeners() to increase limit
```

Uyarı satırının başındaki sayı süreç kimliğidir ve her çalıştırmada değişir. Uyarı
bir hata değildir; program çalışmaya devam eder.

Uyarının gerekçesi şudur: dinleyici listesi büyümeye devam ediyorsa, bu genellikle
her istekte yeni dinleyici eklendiği ve hiç kaldırılmadığı anlamına gelir. Liste
büyüdükçe kapatılan fonksiyonların tuttuğu değerler de serbest bırakılamaz ve bellek
sızıntısı oluşur — Eşzamansız JavaScript ve Çalışma Zamanı kursunda erişilebilirlik
temelli çöp toplama anlatılırken kurulan durum tam olarak budur.

Gerçekten çok dinleyici gerekiyorsa sınır `setMaxListeners` ile yükseltilir. Sınırı
yükseltmeden önce, listenin neden büyüdüğü açıklanmalıdır.

## Olayları Söz Olarak Beklemek

Olay tabanlı arayüzü `async`/`await` ile birleştirmek için modül iki yardımcı sunar.
`once` fonksiyonu tek bir olayı bekleyen söz döndürür; `on` fonksiyonu ise olayları
eşzamansız yinelenebilir hâle getirir.

```js
// yayici-soz.mjs
import { EventEmitter, once, on } from 'node:events';

const kaynak = new EventEmitter();

// Tek bir olayi beklemek: soz olarak
setTimeout(() => kaynak.emit('hazir', { dugum: 'kenar-01' }), 20);
const [yuk] = await once(kaynak, 'hazir');
console.log('once ile beklendi:', yuk);

// Surekli akan olaylari yinelemek
setTimeout(() => {
  kaynak.emit('olcum', 21.4);
  kaynak.emit('olcum', 21.9);
  kaynak.emit('bitti');
}, 20);

const durdurucu = new AbortController();
kaynak.once('bitti', () => durdurucu.abort());

try {
  for await (const [deger] of on(kaynak, 'olcum', { signal: durdurucu.signal })) {
    console.log('akan olay        :', deger);
  }
} catch (hata) {
  if (hata.name !== 'AbortError') throw hata;
  console.log('yineleme sonlandi:', hata.name);
}
```

```sh
node yayici-soz.mjs
```

```
once ile beklendi: { dugum: 'kenar-01' }
akan olay        : 21.4
akan olay        : 21.9
yineleme sonlandi: AbortError
```

Her iki yardımcı da dinleyici argümanlarını dizi olarak verir; tek argümanlı
olaylarda çözümleme ile ilk öğe alınır.

İkinci bölümdeki durdurucu, sonsuz yinelemeyi bitirmenin yoludur. `on` ile kurulan
döngü kendiliğinden sonlanmaz — kaynak olay yaymayı bıraksa bile döngü beklemeye
devam eder. Sonlandırma bir iptal işaretiyle yapılır ve iptal, yineleyiciden bir
`AbortError` olarak çıkar. Bu, Eşzamansız JavaScript ve Çalışma Zamanı kursunda
istek iptali için tanıtılan aynı düzenektir.

Bir uyarı: `on` ile kurulan yineleme, döngü gövdesi çalışırken gelen olayları
biriktirir. Gövde yavaşsa bu birikim sınırsızdır; olay yayıcı, akışların aksine geri
basınç taşımaz. Yüksek hacimli kaynaklarda olay yayıcı yerine akış kullanılmasının
nedeni budur.

## Özet

- Olay yayıcı, ad başına dinleyici listesi tutan gözlemci kalıbı gerçekleştirimidir;
  çalışma zamanının eşzamansız arayüzlerinin çoğu bu sınıfın üstüne kuruludur.
- `emit` eşzamanlıdır: dinleyicileri eklenme sırasına göre o anda çağırır ve hepsi
  bitince döner; yayım işi ertelemez.
- `error` adı ayrıcalıklıdır; dinleyicisiz yayım yükü fırlatır ve süreci sonlandırır.
  Hata yayabilen her nesneye dinleyici takılır.
- Dinleyici sayısı sınırı aştığında yazılan uyarı, çoğunlukla kaldırılmayan dinleyici
  birikimini ve buna bağlı bellek sızıntısını haber verir.
- `once` ve `on` yardımcıları olayları söz ve eşzamansız yineleme biçimine çevirir;
  yineleme bir iptal işaretiyle sonlandırılır ve geri basınç taşımaz.

## Sonraki Adım

Ölçüm toplayıcının bütün parçaları hazır: dosyadan akışla okuma, kayıt kurma,
özetleme ve olay tabanlı bildirim. Eksik olan tek şey, özetin dışarıya sunulmasıdır.
Sonraki ders HTTP sunucusunu kurar: isteğin okunabilir, yanıtın yazılabilir bir akış
olduğu; İnternet Nasıl Çalışır kursunda satır satır incelenen istek ve yanıt
yapısının kodda nasıl karşılandığı ele alınacak.
