מדריך Node.js: מודלים בסיסיים: אירועים

כך יוצרים פונקציות שמאזינות לאירועים ויורים את האירועים ב-Node.js
Node.js Logo

במאמר הקודם למדנו איך משתמשים במודול בסיסי: http. במאמר הזה אנו נלמד על אירועים ב-Node.js. אירועים ב-Node.js הם אחד הדברים החשובים ביותר שאפשר ללמוד. באופן עקרוני, עם eventEmitters אנחנו יכולים ליצור אירועים שאפשר 'להאזין' להם לצרכים שונים. כך למשל, אני יכול 'להאזין' לאירוע יצירת משתמש ומיד אחרי שהוא נוצר לעשות שליחת מייל (למשל). למה לא לעשות את זה עם callbacks?כי שימוש נבון באירועים יכול למנוע מאיתנו את חגיגת ה-callbackים ורמות מטורפות ל nesting. לא מעט מודולים עושים טריגר לאירועים שונים ומשונים ובמקום חגיגת callbacks אפשר פשוט להאזין לאירועים.

השימוש באירועים הוא ממש פשוט. אפשר גם להסתכל על הדוקומנטציה שמכילה את כל המתודות של Events.

ה-require של events צריך להתבצע, כך לפי הדוקומנטציה, באופן הבא:


require('events').EventEmitter.

בואו ונניח שאני רוצה ליצור אירוע – קודם אני אעשה instance ל-class באופן הבא:


var ee = new EventEmitter();

ואז פשוט להפעיל את האירוע על ידי מתודת emit!


ee.emit("myEvent");

מהרגע הזה, כל פונקציה מאזינה שנמצאת בקוד – ולא משנה היכן בקוד, תופעל. אם הפונקציה שיוצרת את האירוע נמצאת במודול, גם אם הפונקציה שמאזינה נמצאת במודול אחר (שעשינו לו require כמובן), אז הפונקציה המאזינה תתפוס את האירוע. גם אם המודול נקרא הרבה אחרי שהמודול שלנו הופעל – פונקצית ההאזנה תפעל.

איך נראית פונקציה שמאזינה? מאוד פשוט:


var EventEmitter = require("events").EventEmitter;
var ee = new EventEmitter();

ee.on("myEvent", function () {
    console.log("event has occured!");
});

ראשית אני מבצע instance ל-events ואז אני משתמש במתודת on כדי להאזין לאירוע שאותו אני מעביר כארגומנט. הארגומנט השני הוא פונקציה אנונימית שמופעלת כאשר מתבצעת הקריאה.

אנו יכולים להעביר כמובן ארגומנטים באירוע שלנו. הנה דוגמה:


var EventEmitter = require("events").EventEmitter;

var ee = new EventEmitter();

/* create listener */
ee.on("myEvent", function (arg1, arg2) {
    console.log("event has occured!");
    console.log("here are the arg1: "+arg1);
    console.log("here are the arg2: "+arg2);
});

/*activating the event */
ee.emit("myEvent",'arg1','arg2');

שימו לב שההאזנה יכולה להתבצע בכל מקום! ה: ee.on יכול להיות בכל מקום! איזה כיף! תעתיקו ותדביקו את הקוד שלעיל ותריצו אותו. נסו להעביר כארגומנטים גם אובייקטים או מערכים ותראו שהם עוברים. מעולה! שווה לתרגל.

הצצה בדוקומנטציה מראה עוד כמה מתודות שוות במיוחד – למשל once – מתודת האזנה שמופעלת פעם אחת בלבד! למשל – כאן אני משתמש ב-once ויורה את האירוע פעמיים. אם אני אריץ את הקוד הזה אני אראה שהפונקציה המאזינה תרוץ רק פעם אחת בלבד ולא פעמיים.

(זוכרים איך להריץ, נכון?? להעתיק, להדביק בקובץ whatever.js ואז להריץ בקונסולה או ב-cmd ככה: nodejs whatever.js).


var EventEmitter = require("events").EventEmitter;

var ee = new EventEmitter();

/* create listener - will not work more than once */
ee.once("myEvent", function (arg1, arg2) {
    console.log("event has occured!");
    console.log("here are the arg1: "+arg1);
    console.log("here are the arg2: "+arg2);
});


/*activating the event */
ee.emit("myEvent",'arg1','arg2');

/*activating the event 2nd time */
ee.emit("myEvent",'arg1','arg2');

אפשר גם לקבל את רשימת המאזינים, למחוק פונקציה מאזינה, להגביל את מספר המאזינים ועוד כמה דברים.

הסברתי קודם לכן ששימוש נבון בפונקציות האזנה יכול לסדר מעט את הקוד של Node.js. איך בדיוק? ככה:


var http = require("http");
var server = http.createServer();
server.listen(3000);

server.on("request", function (request, response) {
    response.setHeader("Set-Cookie", ["type=ninja", "language=javascript"]);
    response.writeHead(200, {"Content-Type": "text/html"});
    response.write("Hello World!");
    response.write(request.httpVersion);
    response.end();
});

console.log("Server running at http://localhost:3000/"); //Printing to the console only

מה שאני עשיתי לא שונה באופן מהותי מהסינטקס שראינו במאמר הקודם:


http = require("http"); //The require

var MyServer = http.createServer(function(request, response) {
    response.setHeader("Set-Cookie", ["type=ninja", "language=javascript"]);
    response.writeHead(200, {"Content-Type": "text/html"});
    response.write("Hello World!");
    response.write(request.httpVersion);
    response.end();
});

MyServer.listen(3000);

console.log("Server running at http://localhost:3000/"); //Printing to the console only

אבל עם האזנה אני יכול ליצור קוד יותר מסודר ולהפריד בין אירוע יצירת ה-server למה שקורה מיד אחרי שהוא נוצר. אפשר לעשות את זה כמעט עם כל מודול. כל מודול משחרר events ובדיקה בקוד שלו או בדוקומנטציה שלו תראה לנו את זה. הדרך הפשוטה ביותר, אגב, היא להשתמש ב-utils על מנת לרשת את events וכך לקבל במתנה את כל המתודות שלו.

מה, רגע? ירושות? אפשר לעשות את זה ב-Node.js Utilities. אבל על זה נדבר במאמר הבא.

⚠️ תזכורת – המדריכים האלו הם רק טעימה, בספר שלי "ללמוד Node.js בעברית" יש הסברים מלאים ומקיפים על השפה המיועדים ללימוד עצמי. עם תרגילים והסברים. הספר יצא לאור בשיתוף הקריה האקדמית אונו ובתמיכת החברות אלמנטור, ו-Iron source ונערך טכנית על ידי בנג'י גרינבאום (מפתח ליבה של Node.js), גיל פינק ומתכנתים מעולים נוספים. 

פוסטים נוספים שכדאי לקרוא

תמונה מצוירת של רובוט שמנקה HTML
יסודות בתכנות

סניטציה – למה זה חשוב

הסבר על טכניקה פשוטה וידועה מאד שאנו מפעילים על מידע לפני שאנחנו מציגים אותו ב-HTML באפליקציה או באתר.

פתרונות ומאמרים על פיתוח אינטרנט

המנעו מהעלאת source control לשרת פומבי

לא תאמינו כמה אתרים מעלים את ה-source control שלהם לשרת. ככה תמצאו אותם וגם הסבר למה זה רעיון רע.

פתרונות ומאמרים על פיתוח אינטרנט

יישום של nonce על מנת להגן מפני התקפות injection

בפוסט הקודם הסברתי על hash עם CSP על משאבי inline – שזה נחמד ומעולה אבל פחות ישים בעולם האמיתי שבו בדרך כלל התוכן ה-inline (בין

ספריות ומודולים

להתנסות ב AutoGPT

הטרנד החם בעולם ה-GPT וה-AI – הפעלת אייג׳נטים בקלות עם Auto GPT.

גלילה לראש העמוד