Event Bus ونمط Observer في JavaScript (Node.js) — بناء أنظمة أحداث مرنة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

Event Bus ونمط Observer في JavaScript (Node.js)

في التطوير الحديث باستخدام Node.js، غالبًا ما تنشأ الحاجة إلى تنظيم التفاعل بين مكونات التطبيق المختلفة دون إنشاء روابط صلبة بينها. يوفر نمط Observer (المراقب) وتطبيقه الأكثر قوة — Event Bus (ناقل الأحداث) — حلاً أنيقًا لهذه المشكلة. في هذه المقالة، سنشرح بالتفصيل كيفية تطبيق هذه الأنماط باستخدام JavaScript الخالص في بيئة Node.js، وسنناقش مزاياها وسيناريوهات الاستخدام النموذجية.



ما هو نمط Observer؟

يحدد نمط Observer علاقة "واحد إلى متعدد" بين الكائنات: عندما يغير كائن واحد (الموضوع) حالته، يتم إخطار جميع الكائنات التابعة له (المراقبون) تلقائيًا بذلك. في سياق Node.js، يشكل هذا النمط أساس الوحدة المدمجة events، التي توفر الفئة EventEmitter.



Event Bus: توسيع المفهوم

Event Bus هو ناقل أحداث مركزي يسمح لأي مكون من مكونات التطبيق بإرسال واستقبال الرسائل دون معرفة بعضهم البعض بشكل مباشر. هذا مفيد بشكل خاص في بنية الخدمات المصغرة، والتطبيقات المعقدة ذات البنية المعيارية، أو عند بناء أنظمة إضافات.



تطبيق Event Bus في Node.js

لننظر في إنشاء Event Bus خاص بنا من الصفر. ستدعم فئتنا الطرق الأساسية: الاشتراك في الأحداث (on)، الاشتراك لمرة واحدة (once)، إزالة المشتركين (off)، وإصدار الأحداث (emit).



class EventBus {    constructor() {        this.events = {};    }

on(event, listener) { if (!this.events[event]) { this.events[event] = []; } this.events[event].push(listener); return () => this.off(event, listener); }

once(event, listener) { const wrapper = (...args) => { listener(...args); this.off(event, wrapper); }; this.on(event, wrapper); return () => this.off(event, wrapper); }

off(event, listener) { if (!this.events[event]) return; this.events[event] = this.events[event].filter(l => l !== listener); }

emit(event, ...args) { if (!this.events[event]) return false; this.events[event].forEach(listener => listener(...args)); return true; }}

// مثال على الاستخدامconst bus = new EventBus();

const unsubscribe = bus.on('user:login', (username) => { console.log(`المستخدم ${username} قام بتسجيل الدخول`);});

bus.once('app:start', () => { console.log('تم تشغيل التطبيق (إخطار لمرة واحدة)');});

// إصدار الأحداثbus.emit('app:start'); // "تم تشغيل التطبيق (إخطار لمرة واحدة)"bus.emit('user:login', 'آنا'); // "المستخدم آنا قام بتسجيل الدخول"

// إلغاء الاشتراكunsubscribe();bus.emit('user:login', 'إيفان'); // لن يحدث شيء


استخدام EventEmitter المدمج من Node.js

توفر Node.js تطبيقًا جاهزًا لـ EventEmitter في الوحدة events. ومع ذلك، فإن Event Bus الذي تم إنشاؤه بناءً عليه يسمح بإدارة مركزية لجميع أحداث التطبيق.



const EventEmitter = require('events');

class AppEventBus extends EventEmitter { constructor() { super(); this.setMaxListeners(50); // زيادة حد المشتركين }

// إضافة تسجيل للتصحيح emit(event, ...args) { console.log(`[EventBus] الحدث: ${event}`); return super.emit(event, ...args); }}

const appBus = new AppEventBus();

// الاشتراك في الأحداثappBus.on('order:created', (order) => { console.log(`تم إنشاء الطلب #${order.id}. جاري إرسال الإخطار.`);});

appBus.on('order:created', (order) => { console.log(`تم إنشاء الطلب #${order.id}. جاري تحديث المخزون.`);});

// الإصدارappBus.emit('o

توصيات