আপনি আগে ব্রাউজার JavaScript-এ ইভেন্ট ব্যবহার করেছেন — button.addEventListener('click', ...)। Node-এর একই ধারণার নিজস্ব সংস্করণ আছে, EventEmitter নামের একটি ক্লাসের চারপাশে তৈরি, আর Node-এর নিজের অনেক বিল্ট-ইন API এর উপরেই তৈরি।
const EventEmitter = require('events')
const emitter = new EventEmitter()একটি নামযুক্ত ইভেন্ট ঘটলে চালানোর জন্য on() একটি ফাংশন রেজিস্টার করে। emit() সেটি ট্রিগার করে:
emitter.on('greet', (name) => {
console.log(`Hello, ${name}!`)
})
emitter.emit('greet', 'Priya') // লগ করে: Hello, Priya!emit()-এ পাস করা যেকোনো অতিরিক্ত আর্গুমেন্ট প্রতিটি listener-এ ফরওয়ার্ড হয়। আর একটি একক ইভেন্টের একাধিক listener থাকতে পারে — সবগুলো চলে, যে ক্রমে সেগুলো রেজিস্টার হয়েছিল সেই ক্রমে।
const EventEmitter = require('events')
class OrderSystem extends EventEmitter {
placeOrder(item) {
console.log(`Order placed: ${item}`)
this.emit('order-placed', item)
}
}
const orders = new OrderSystem()
orders.on('order-placed', (item) => {
console.log(`Sending confirmation email for: ${item}`)
})
orders.on('order-placed', (item) => {
console.log(`Updating inventory for: ${item}`)
})
orders.placeOrder('Laptop Stand')placeOrder মেথডের ইমেইল বা ইনভেন্টরি সম্পর্কে কিছু জানার প্রয়োজন নেই — এটি শুধু ঘোষণা করে যে একটি অর্ডার হয়েছে। যা কিছু এতে আগ্রহী তা এটি শুনতে পারে। placeOrder-এ কোনো পরিবর্তন ছাড়াই শুধু আরেকটি on() listener যুক্ত করে পরে নতুন আচরণ যোগ করা যায়।
এটি ঠিক সেই আকার যা Node নিজেই ভেতরে ব্যবহার করে। একটি ফাইল স্ট্রিম chunk আসার সাথে সাথে 'data' emit করে আর শেষ হলে 'end'; একটি HTTP সার্ভার প্রতিটি আগত রিকোয়েস্টের জন্য 'request' emit করে। এখানে EventEmitter বোঝা পরের বেশ কয়েকটি পাঠে কভার করা সেই বিল্ট-ইন API-গুলোকে অনেক কম রহস্যময় করে তোলে।
একটি ইভেন্ট নাম শুধু আপনার বেছে নেওয়া একটি স্ট্রিং — কোনো নির্দিষ্ট তালিকা নেই। 'order-placed' কাজ করে কারণ emitter আর listener উভয়ই ঠিক সেই বানানটি ব্যবহার করতে একমত। যেকোনো একটিতে একটি টাইপো মানে listener চুপচাপ কখনো চলে না।