Menu

Node.js EventEmitter: on, emit, once ve Özel Olaylar

Node'un events modülündeki EventEmitter, bir nesnenin emit ile isimli olaylar duyurmasını, diğer kodun da on ya da once ile bunlara tepki vermesini sağlar. Listener'lar senkron çalışır, eklendikleri sırayla.

Bu sayfada çalıştırılabilir editörler var. Düzenle, çalıştır ve sonucu anında gör.

EventEmitter, Node'un events modülünde bulunan ve bir nesnenin isimli olaylar duyurmasını sağlayan sınıftır. emitter.on('name', fn) ile bir listener kaydedersin ve emitter.emit('name', ...args) ile onu tetiklersin; o isimdeki her listener, eklendiği sırayla ve verdiğin argümanlarla çalışır. HTTP sunucuları, stream'ler ve process birer EventEmitter'dır, bu yüzden aynı birkaç metot Node'un her yerinde çalışır.

İki listener da before emit ile after emit arasında çalışır: emit onları senkron çağırır ve ancak bittiklerinde döner. İki shop.on çağrısının yerini değiştirirsen ortadaki iki satırın da yeri değişir.

on, once ve off

on bir listener'ı sen silene kadar tutar, once onu ilk çağrıdan sonra siler, off (removeListener ile aynı) ise birini siler. Bir listener'ı silmek için eklediğin fonksiyonun aynısına ihtiyacın var, bu yüzden arrow function'ı satır içinde vermek yerine fonksiyona bir isim ver.

first open ever bir kez, Ada'dan sonra yazdırılır. logOpen silindikten sonra dinleyen kimse kalmaz, bu yüzden son emit false döndürür; door.removeAllListeners('open') iki listener'ı tek çağrıda temizlerdi.

MetotNe yapar
on(name, fn), addListenerHer emit'te fn'i çağırır
once(name, fn)fn'i yalnızca bir sonraki emit'te çağırır
prependListener(name, fn)on gibi, ama mevcut listener'lardan önce çalışır
off(name, fn), removeListenerO fonksiyonu siler
emit(name, ...args)Listener'ları çağırır, en az biri varsa true döndürür
listenerCount(name)Olayın kaç listener'ı olduğu

error olayı

'error' özeldir. Onu emit edersen ve kimse dinlemiyorsa emit hatayı fırlatır ve gerçek bir programda yakalanmamış bir throw süreci çökertir. Stream'ler ve sunucular gibi hata verebilecek emitter'lara her zaman bir 'error' listener'ı ekle.

Listener yokken emit hata fırlatır ve onu catch yakalar; listener eklendikten sonra aynı emit sadece onu çağırır ve program devam eder. Listener'ı olmayan diğer olay isimleri sessizce yok sayılır.

Kendi sınıfında EventEmitter'ı extend et

Olağan kullanım şekli, sınıfının EventEmitter'ı extend etmesi, constructor'da super() çağırması ve bir şey olduğunda this.emit kullanmasıdır. Sonra çağıranlar nesnene herhangi bir Node nesnesine abone olur gibi abone olur.

Önce 25%, 50%, 75%, 100%, ardından photo.png uploaded yazdırılır. up.start() satırını iki up.on satırının üstüne taşırsan hiçbir şey yazdırılmaz: olaylar kimse dinlemeden tetiklenir.

Aynı tuzak constructor'dan emit ederken de geçerlidir. Hemen emit etmesi gereken kütüphaneler çağrıyı process.nextTick ile sarar; bu, çağıranın on satırlarından sonra çalışır (bkz. event loop sayfası).

events.once ile bir olayı bekle

events.once(emitter, name), olay bir sonraki sefer emit edildiğinde olayın argümanlarıyla, bir dizi olarak, resolve olan bir promise döndürür. Tek seferlik bir olayı await edebileceğin bir şeye çevirir ve emitter önce 'error' emit ederse reject olur.

await, timer ready olayını emit edene kadar bekler, sonra dizi iki argümana ayrıştırılır. Birçok kez tetiklenen bir olay için events.on(emitter, name), for await ile üzerinde döngü kurabileceğin bir async iterator verir.

Sık yapılan hatalar

Sık çalışan bir fonksiyonun içinde listener eklemek. Her request handler'da on çağırmak listener'ları ve belleği üst üste yığar. Bir kez ekle ya da once kullan.

Satır içi bir fonksiyonu silmeye çalışmak. off('data', () => ...) hiçbir şey silmez, çünkü o arrow function yepyeni bir fonksiyondur. Eklediğin fonksiyona bir referans tut.

Listener'ların daha sonra çalışmasını beklemek. emit senkrondur, yani yavaş bir listener emit eden kodu bekletir. Listener'ı async yapmak işe yaramaz, çünkü kodu ilk await satırına kadar yine aynı thread'de çalışır. Ağır işi aralarına setImmediate koyarak parçalara böl ya da bir worker thread'e taşı.

Sıkça Sorulan Sorular

EventEmitter asenkron mu?

Hayır. emit her listener'ı hemen, birbiri ardına çağırır ve sonuncusu bitince döner. Bir listener'ın içindeki kod async bir iş başlatabilir, ama listener'ın kendisi senkron çağrılır.

MaxListenersExceededWarning ne anlama geliyor?

Node, bir olay için 10'dan fazla listener eklendiğinde uyarır, çünkü bu genelde her istekte bir listener eklenip hiç silinmediği anlamına gelir. Fazla listener'ları sil ya da gerçekten daha fazlasına ihtiyacın varsa emitter.setMaxListeners(n) çağır.

emit ne döndürür?

Olayın en az bir listener'ı varsa true, kimse dinlemiyorsa false. Listener'ların döndürdüğü değeri döndürmez.

Hangi Node.js nesneleri EventEmitter'dır?

Node'un çekirdek nesnelerinin çoğu: HTTP sunucuları, request ve response'lar, stream'ler, soketler, process ve readline arayüzleri. Hepsinin on, once ve off metotlarını paylaşmasının nedeni bu.

Coddy programlama dilleri çizimi

Coddy ile kodlamayı öğren

Başla