מימוש עצמי של אירועים
-
הדרך הטובה ביותר להבין איך מתרחשים אירועים - היא ליצור אותם בעצמך
אז כדי להבין את המושג האזנה לאירוע, ניסיתי לממש בעצמי מחלקה שמטפלת בנושא.
הדרישה היא – לספק API עם 2 אפשרויות, הרשמה לאירוע והפעלת האירוע, כולל אפשרות להעביר מידע מותאם אישית יחד עם האירוע.
הדרך המתבקשת היא לעבוד עם אוביקט שמכיל מפתחות שהם שמות האירועים, והערך של כל מפתח הוא מערך של פונקציות שהם הקולבקים, וכאשר "יתרחש" האירוע, כלומר כשמישהו יחליט לפלוט אירוע, נעבור בלולאה על המערך ונריץ את כל הקולבקים, ונעביר להם את המידע. האובייקט אמור להיראות כך:{ "click": [ function name (params) { ...params } ], "myEvent": [ function name (params) { ...params }, function name (params) { ...params } ] }
ובכן נתחיל עם המחלקה, בשבל הראשון נחקה את מודל האירועים של נוד, שזה אובייקט גלובלי שכל מי שיש לו גישה אליו יכול להרשם ולפלוט אירועים, ראשית נאתחל נכס פרטי בשם _events שהוא יהיה האובייקט שישמור את כל האירועים והקולבקים. וגם ניצור את המתודה on שדרכה ירשמו לאירועים, מי שרוצה להרשם לאירוע יעביר 2 פרמטרים למתודה on – שם האירוע, והפונקציה שהוא רוצה שתתרחש כשיפלט האירוע
class EventEmitter { _events = {}; on (eventId, callback) { this._events[eventId] = this._events[eventId] || []; this._events[eventId].push(callback); } }
נבדוק שזה עובד, ניצור מופע של המחלקה, ונרשם להאזנה לאירוע:
ניתן לראות שהנכס הפרטי מכיל את האירוע והקולבק שהעברנו לו.עכשיו נוסיף למחלקה מתודה בשם emit שדרכה יתאפשר להכריז על התרחשות האירוע, היא תקבל גם 2 פרמטרים, שם האירוע והמידע שישלח יחד עם האירוע.
emit (eventId, args) { if (!this._events[eventId]) return; for (let callback of this._events[eventId]) { callback(args) } }
ובכן, זה עובד. כל מי שיש לו גישה ל events יוכל להרשם ולפלוט אירועים.
בשלב השני, נחקה את ההתנהגות של הדפדפן, האירועים מוצמדים לאלמנטים, כל אלמנט DOM מאפשר אירועים פרטיים, לדוגמא כל כפתור פולט אירוע click כשלוחצים עליו, ואפשר לקבל הודעה על האירוע הפרטי של אלמנט מסוים.
הדרך לעשות את זה פשוטה, נדאג שכל אלמנט יירש מהמחלקה של האירועים. לדוגמא ניצור מחלקה של רכב עם ירושה.class Car extends EventEmitter {}
כעת ניצור שני סוגי רכבים, ונראה שאפשר ליצור מטפל לכל אירוע מכל רכב בנפרד: