
const EventEmitter = require('events'), ואז class Car extends EventEmitter. בקונסטרקטור קוראים ל-super().drive מוריד דלק בכל נסיעה. הנסיעה חוזרת כל שנייה בעזרת setInterval, כי לולאה רגילה הייתה חוסמת את Node.js.clearInterval עוצר את הטיימר לפי המזהה שלו.this.emit('no-fuel') מדווח שהדלק נגמר, בלי לדעת מי מאזין.this.emit('low-fuel', { fuelLeft }) שולח אובייקט עם הנתון, כך שהמאזין יכול להשתמש בו.car.on('no-fuel', ...) מאזין לאירוע באותו שם בדיוק. car.on('low-fuel', (args) => ...) מקבל את הארגומנטים שנשלחו.הטקסט המלא של הדקות הראשונות בהרצאה «אירועים EVENTS ב-NodeJS» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
ראינו את כל הכלים שקיימים באובג'קט אוריינטד, שזה אינקפסוליישן, אינהריטנס, פולימורפיזם, אבסטרקטיות וכל האלמנטים הסטטיים, אבל יש עוד נושא אחד שהוא כן איכשהו מתקשר לאובג'קט אוריינטד בצורה מאוד חזקה, וכן הייתי רוצה להכניס אותו לנושא הזה, לנושא הזה של אובג'קט אוריינטד, וזה איבנטים, אירועים.
אירוע אנחנו יודעים שזה בעצם איזושהי פעילות שמתרחשת מתוך המחלקה, אנחנו מדווחים משהו החוצה ומחלקה חיצונית יותר שמשתמשת איתנו יכולה לתפוס את האירוע ולבצע איתו איזושהי פעולה. בגלל שיש פה ממש קשר הדוק למחלקות, לדיווחים, אז זה כמובן מאוד קשור גם ל-object oriented.
אנחנו רוצים לראות איך אנחנו יכולים לבצע איבנטים ב-node.js. אז לצורך כך בואו נבנה מחלקה חדשה שמתארת מכונית.
יש לנו קלאס r היא לא יורשת שום דבר ואנחנו רוצים לחשוף אותה החוצה. מודול exports r. בתוך car בואו נבנה קונסטרקטור ובקונסטרקטור עצמו יש יצרן ויש מודל. בואו נבצע דיס נקודה מניפקטור שווה מניפקטור דיס נקודה מודל שווה מודל.
בנוסף יש לנו פונקציה שנקראת דרייב ואנחנו רוצים לבצע הדמיה כאילו שאנחנו נוסעים אז בואו נייצר פה קונסול לוג דרייבינג. אוקיי הנה מחלקה ראשונה בואו נייצר מחלקה שנייה שנקראת גיים יש לנו קובץ game.js האמת, את ה-car בכלל רציתי לייצר בתוך rjs, לא שמתי לב שכתבתי אותה ב-up, ביי ביי.
הנה יש לנו car.js, בתוכה יש את המחלקה car, ויש לנו game, ובתוך game אנחנו רוצים מחלקה שמתארת משחק מכוניות. אז יש לנו class Game, ואנחנו רוצים פונקציה סטארט, ויש לנו כאן קונסט r שווה rickwire של r.
גיים מאוד סימפל, אנחנו יוצרים מכונית car שווה new car, ואנחנו נותנים ליצרן, למורגיני ומודל דיאבלו, ואנחנו פשוט מבצעים נסיעה car.drive, ואנחנו אמורים לראות על המסך שאנחנו דרייבינג.
בואו נבצע מודול נקודה אקספורטס שווה גיים. כעת אנחנו יכולים לגשת לאפ, לייבא את גיים, ויש לנו פה קונסט גיים שווה ריקווייר גיים.
גיים נקודה סטארט. אנחנו רוצים להתחיל את המשחק שלנו, אז בואו נריץ את זה, נוד אפ, גיים סטארט is not a function. למה הוא צועק עליי? בואו נראה, סטארט כתבתי כמו שצריך, אוי, זה בכלל אמור להיות עם ג'י גדולה, ואני רואה שלא יצרנו בכלל, לא יצרתי בכלל, משחק פונסט גיים שווה ניו גיים, ועכשיו זה אמור להיות בסדר.
יופי, דרייבינג, אז יש לנו משחק מכוניות, יש לנו מכונית, ויש לנו את האפליקציה שמתחילה את המשחק ואז כל מה שקורה במשחק זה שהמכונית נוסעת. אני רוצה טיפה להוסיף פה איזשהו משהו מעניין בתוך Drive.
אני רוצה להוסיף בתוך Drive גם דלק. נתחיל עם 10, נניח, ליטר דלק. ומה שאני רוצה לעשות זה לעשות הדמיה כאילו שאני באמת נוסע במכונית. דרייבינג, דרייבינג, דרייבינג.
וכל פעם שאני נוסע, אז כמובן הדלק מתבזבז לו, שזה בסדר, אבל באיזשהו שלב כבר לא יהיה דלק יותר ולכן אנחנו נפסיק לנסוע, אם אנחנו לא נמלא דלק כמובן.
איך אנחנו מבצעים משהו שוב ושוב ושוב? אם אני אקח לולאה, כמובן היא תתבצע תוך שנייה, תוך שבריר שנייה. אם אני אעשה איזשהו דיליי בלולאה של איזושהי לולאה שלא עושה כלום זה כמובן לא טוב כי זה יהיה בלוקינג אופריישן ויעצור לנו את כל האקסקיושן של Node.js מה גם שבכל מחשב הוא ירוץ אחרת זה לא השיטה הנכונה.
השיטה הנכונה זה to set interval. set interval זה שוב פעם אחת מהפונקציות שמאפשרות להריץ קטע קוד באזור של ה-C++ APIs כך שהוא לא יפריע להריצה הרגילה של Node.js אז בואו ניתן לו פונקציה ונגיד לו שהוא יריץ את הפונקציה הזאת כל שנייה.
בואו ניכנס ובתוך הפונקציה נרשום דרייבינג אבל זה לא יפסיק כלומר הוא תמיד תמיד תמיד בלי הפסקה יבצע דרייבינג אנחנו רוצים גם לעצור את הדרייבינג כתלות בדלק אז קודם כל אחרי שנסענו קצת עשינו הדמיה כאילו אנחנו מבצעים נסיעה בואו נוריד מהדלק.
נבצע לדוגמה פיול מינוס מינוס. עכשיו אם פיול אפס אנחנו רוצים לעצור את הטיימר אבל איך אני יוצר טיימר בג'אווה סקריפט? לעצור טיימר בג'אווה סקריפט זה פשוט לקבל את הכתובת של הטיימר או איזשהו מזהה ID של הטיימר אלינו ואז להשתמש בפונקציה שנקראת clear interval ולתת לה את אותו מזהה כעת אנחנו בעצם נרוץ מספר פעמים ואנחנו נעצור בואו רגע
נסתכל על זה ננקה אני רואה שעוד פעם הוא לא מנקה לא קרה כלום בואו נסגור את הטרמינל ונפתח מחדש איזה שהוא באג של visual studio טוב אז אנחנו רוצים to ויש לנו מספר פעמים דרייבינג בואו נראה כמה פעמים 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 בדיוק כמו שאנחנו יודעים הוריד ל-9 הוריד ל-8 ברגע שיש לו 0 אז הוא סיים כי אין לו יותר דלק עד כאן זה מאוד פשוט מה הקשר לאירועים אז
בואו נסתכל רגע מה המחלקות שיש לנו יש לנו מחלקה שמתארת מכונית ויש לה איזשהו דלק פנימי של המכונית. יש לנו מחלקה שמתארת משחק מכוניות.
המשחק מכוניות הוא זה ששולט במכונית ואומר לה ננסוע, אבל המכונית עצמה יודעת מה מצב הדלק שלה, זה הגיוני. עכשיו, ברגע שאין לנו דלק אנחנו רוצים להודיע למשחק שאין לנו דלק כדי שהמשחק בעצם יעשה מה שהוא רוצה לעשות בנוגע לזה.
לדוגמה, יציג הודעה של Game Over, יציג הודעה שאתה חייב להיכנס לתחנת דלק, לא משנה מה. האם המחלקה Car מכירה את המחלקה Game?
או האם המחלקה Game מכירה את המחלקה Car? מי מכיר את מי? האם אני יכול פה למעלה לרשום Require עבור Game, ובגיים ריקווייר עבור קאר.
אז התשובה היא כזאת, המחלקה גיים צריכה להכיר את המחלקה קאר מפני שהיא רוצה לבנות אובייקט מהמחלקה קאר ולכן היא מבצעת ריקווייר. המחלקה גיים לא מכירה את המחלקה קאר, סליחה, המחלקה קאר לא מכירה את המחלקה גיים ולא אמורה להכיל ריקווייר פה למעלה. זה לא יהיה נכון ולדעתי אפילו יעשה איזשהו סירקולר רפרנס כזה, יש מצב, כן?
לא בטוח שזה מה שיקרה בנו ג'י אס פה אבל בגרסה הזאת אבל יש מצב שזה מה שיקרה ולכן אנחנו לא רוצים לעשות את זה זה גם לא נכון שמחלקה א' תכיר מחלקה ב' ומחלקה ב' תכיר מחלקה א' בהקשר הזה.
אז מה כן אנחנו רוצים לעשות? אנחנו איכשהו רוצים מתוך המחלקה car לשלוח הודעה למחלקה game מבלי להכיר את המחלקה game ולצורך כך בדיוק יש לנו את הקונספט של events. אז איך אנחנו מיישמים איבנטים ב-Node.js?
הדבר הראשון שאנחנו צריכים לעשות זה במחלקה car לבנות אובייקט שהוא קלאס מסוג Event Emitter, ויש לנו Require Events. זה בעצם תשתית מוכנה שקיימת ב-Node.js שאומרת לנו אני מסוגלת לתת לכם שירותים של איבנטים ויש לי מחלקה שנקראת Event Emitter, שימו לב ל-E הגדולה כי זה לא פונקציה, זה קלאס.
הדבר הבא שאנחנו צריכים לעשות זה לרשת את EventEmitter עבור המחלקה CarExtendsEventEmitter. ככה זה מתבצע ב-Node.js. אחרי שיצרנו אותו אנחנו חייבים כאן לקרוא ל-Super בלי כלום.
זה חלק ממה שמחייבים אותנו לבצע. מעכשיו יש לי אפשרות לדווח אירועים במחלקה שלי. אז איך אני מדווח אירועים? אז בעצם מתי אני רוצה לדווח שמשהו קרה?
אירוע זה דיווח שמשהו קרה בפעילות פנימית של המחלקה. ברגע שאין לי יותר דלק, אז אני רוצה לעצור את הטיימר, או לפני או אחרי להגיד לו שבעצם אין לי יותר דלק.
אז בואו ניגש לדיס נקודה אמית. אמית זה בעצם פונקציה שמגיעה מהאיבנט אמיטר. אנחנו יכולים גם סופר נקודה אמית או דיס נקודה אמית ולהגיד לו, לתת לו את השם של האירוע ואם יש לנו פרמטרים נוספים שאנחנו רוצים להעביר, אנחנו יכולים גם להעביר אותם.
בוא נניח שהשם של האירוע זה nofuel. זה כל האירוע, בוא נניח שאין לי פרמטרים שאני רוצה לדווח, תכף נבנה עוד אירוע עם פרמטרים. עכשיו, מה שקרה ושאנחנו דיווחנו בדיוק בנקודה הזאת אירוע, ובואו רגע נריץ, נוריד את זה רגע ל-4, בכדי שזה יהיה קצת יותר מהיר,
ויש לנו דרייבינג, דרייבינג, דרייבינג, דרייבינג, אבל אף אחד לא האזין לאירוע הזה, ולכן לא ביצע פעולה כאשר אנחנו העלינו את האירוע.
מי זה שאמור להאזין לאירוע? גיים. ברגע שגיים יוצרת אובייקט R, אז היא צריכה מה שנקרא להירשם לאירוע. הפעולה הזאת נקראת raising an event ואנחנו רוצים to register an event.
Registers event זה אומר שאנחנו נרשמים לאירוע וכאשר האירוע עולה אז אנחנו רוצים לדעת מזה ולבצע פעולה בהתאם. כל מה שאנחנו צריכים לעשות זה car.on זה