فئة باعث الأحداث العامة
ابنوا باعث أحداث قابلًا لإعادة الاستخدام ومحدد الأنواع من الصفر
فئة باعث الأحداث العامة درس مجاني في TypeScript Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في TypeScript Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة TypeScript Academy 4 دروس في المجموع.
الهدف: فئة TypedEmitter
سننشئ فئة TypedEmitter<E> قابلة لإعادة الاستخدام، عامة بالنسبة إلى خريطة أحداث E، وتحتوي على طرق on وoff وemit محددة الأنواع بالكامل.
interface Events { login: { userId: string }; logout: void }
// class TypedEmitter<Events> will manage handlers safely.
console.log("building a typed emitter");اسم مستعار لنوع المعالج
عرّف نوع معالج مَعْلَمًا باسم الحدث، حتى يتلقى كل مستمع الحمولة الصحيحة.
type Handler<E, K extends keyof E> = (payload: E[K]) => void;
// E[K] is the payload type for event K in map E.
console.log("handler typed by E[K]");خريطة listeners
خزّن المعالجات مع فهرستها حسب اسم الحدث. ويمنح النوع المعيّن كل مفتاح مصفوفة من المعالجات المحددة النوع بشكل صحيح.
class TypedEmitter<E> {
private listeners: { [K in keyof E]?: Array<(p: E[K]) => void> } = {};
}
console.log("listeners map ready");تنفيذ on
تلحق الطريقة on معالجًا بمصفوفة حدثه، وتنشئ المصفوفة عند أول استخدام.
class TypedEmitter<E> {
private listeners: { [K in keyof E]?: Array<(p: E[K]) => void> } = {};
on<K extends keyof E>(event: K, handler: (p: E[K]) => void): void {
(this.listeners[event] ||= []).push(handler);
}
}
console.log("on implemented");تنفيذ emit
تبحث الطريقة emit عن معالجات الحدث وتستدعي كل معالج بالحمولة محددة النوع.
class TypedEmitter<E> {
private listeners: { [K in keyof E]?: Array<(p: E[K]) => void> } = {};
on<K extends keyof E>(e: K, h: (p: E[K]) => void) { (this.listeners[e] ||= []).push(h); }
emit<K extends keyof E>(e: K, payload: E[K]): void {
(this.listeners[e] || []).forEach(h => h(payload));
}
}
console.log("emit implemented");تنفيذ off
تزيل الطريقة off معالجًا مسجّلًا سابقًا من خلال تصفيته خارج المصفوفة.
class TypedEmitter<E> {
private listeners: { [K in keyof E]?: Array<(p: E[K]) => void> } = {};
on<K extends keyof E>(e: K, h: (p: E[K]) => void) { (this.listeners[e] ||= []).push(h); }
off<K extends keyof E>(e: K, h: (p: E[K]) => void) {
this.listeners[e] = (this.listeners[e] || []).filter(x => x !== h);
}
}
console.log("off implemented");جمع الفئة
إليك الفئة كاملة بطرقها الثلاث، وهي عامة بالنسبة إلى أي خريطة أحداث توفّرها.
class TypedEmitter<E> {
private listeners: { [K in keyof E]?: Array<(p: E[K]) => void> } = {};
on<K extends keyof E>(e: K, h: (p: E[K]) => void) { (this.listeners[e] ||= []).push(h); }
off<K extends keyof E>(e: K, h: (p: E[K]) => void) { this.listeners[e] = (this.listeners[e] || []).filter(x => x !== h); }
emit<K extends keyof E>(e: K, p: E[K]) { (this.listeners[e] || []).forEach(h => h(p)); }
}
console.log("TypedEmitter complete");استخدام TypedEmitter
أنشئ مثيلًا باستخدام خريطة أحداث محددة. والآن أصبحت on وemit محددتين بالكامل من ناحية الأنواع لهذه الأحداث.
class TypedEmitter<E> {
private listeners: { [K in keyof E]?: Array<(p: E[K]) => void> } = {};
on<K extends keyof E>(e: K, h: (p: E[K]) => void) { (this.listeners[e] ||= []).push(h); }
emit<K extends keyof E>(e: K, p: E[K]) { (this.listeners[e] || []).forEach(h => h(p)); }
}
interface Events { login: { userId: string } }
const bus = new TypedEmitter<Events>();
bus.on("login", p => console.log("hi", p.userId));
bus.emit("login", { userId: "u1" });اكتشاف أخطاء الأنواع
ترفض الفئة الأحداث غير المعروفة والحمولات الخاطئة أثناء الترجمة، تمامًا كما فعلت الدوال المستقلة.
class TypedEmitter<E> {
private listeners: { [K in keyof E]?: Array<(p: E[K]) => void> } = {};
on<K extends keyof E>(e: K, h: (p: E[K]) => void) { (this.listeners[e] ||= []).push(h); }
emit<K extends keyof E>(e: K, p: E[K]) { (this.listeners[e] || []).forEach(h => h(p)); }
}
interface Events { ping: { at: number } }
const bus = new TypedEmitter<Events>();
// bus.emit("pong", { at: 1 }); // Error
bus.emit("ping", { at: 1 });
console.log("typed bus");معالجات متعددة لكل حدث
بما أن كل حدث يرتبط بمصفوفة، يمكنك تسجيل العديد من المعالجات، وستُستدعى جميعًا عند استخدام emit.
class TypedEmitter<E> {
private listeners: { [K in keyof E]?: Array<(p: E[K]) => void> } = {};
on<K extends keyof E>(e: K, h: (p: E[K]) => void) { (this.listeners[e] ||= []).push(h); }
emit<K extends keyof E>(e: K, p: E[K]) { (this.listeners[e] || []).forEach(h => h(p)); }
}
interface Events { tick: { n: number } }
const bus = new TypedEmitter<Events>();
bus.on("tick", p => console.log("a", p.n));
bus.on("tick", p => console.log("b", p.n));
bus.emit("tick", { n: 7 });أساس يمكنك توسيعه
تُعد هذه الفئة أساسًا متينًا. وسنحسّن في الخطوة التالية استنتاج معاملات المستمعين، ونضيف دلالات once.
class TypedEmitter<E> {
private listeners: { [K in keyof E]?: Array<(p: E[K]) => void> } = {};
on<K extends keyof E>(e: K, h: (p: E[K]) => void) { (this.listeners[e] ||= []).push(h); }
emit<K extends keyof E>(e: K, p: E[K]) { (this.listeners[e] || []).forEach(h => h(p)); }
}
const bus = new TypedEmitter<{ go: void }>();
bus.on("go", () => console.log("go!"));
bus.emit("go", undefined as void);تحقق سريع: فئة الباعث العام
اختبر مدى فهمك لفئة باعث الأحداث العامة.
مراجعة: فئة باعث الأحداث العامة
أنشأت TypedEmitter<E> مع مخزن مستمعين يعتمد على نوع معيّن، وطرق on وoff وemit محددة الأنواع بالكامل، مما يمنحك نظام نشر/اشتراك قابلًا لإعادة الاستخدام وآمنًا من ناحية الأنواع لأي خريطة أحداث.
class TypedEmitter<E> {
private listeners: { [K in keyof E]?: Array<(p: E[K]) => void> } = {};
on<K extends keyof E>(e: K, h: (p: E[K]) => void) { (this.listeners[e] ||= []).push(h); }
emit<K extends keyof E>(e: K, p: E[K]) { (this.listeners[e] || []).forEach(h => h(p)); }
}
const bus = new TypedEmitter<{ hi: { name: string } }>();
bus.on("hi", p => console.log(p.name));
bus.emit("hi", { name: "Ada" });الأسئلة الشائعة
هل درس «فئة باعث الأحداث العامة» مجاني؟
نعم — نص درس «فئة باعث الأحداث العامة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة TypeScript Academy، انتقل إلى CoddyKit PRO. تتضمن دورة TypeScript Academy 4 دروس في المجموع.
ماذا ستتعلم في «فئة باعث الأحداث العامة»؟
ابنوا باعث أحداث قابلًا لإعادة الاستخدام ومحدد الأنواع من الصفر تتمرن على TypeScript Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ TypeScript Academy؟
لا تُشترط خبرة سابقة. TypeScript Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «فئة باعث الأحداث العامة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس TypeScript Academy هذا؟
نعم. كل درس في TypeScript Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تحديد أنواع خرائط الأحداث
- emit وon الآمنان نوعيًا
- فئة باعث الأحداث العامة
- استنتاج وسائط المستمعين