מדריך Node.js: קוד אסינכרוני

במאמר הקודם למדנו על סביבת העבודה של Node.js – איך מתקינים את Node.js על לינוקס או על חלונות. ואיך עובדים על Node.js באמצעות יצירת קובץ js והרצה שלו עם nodejs.

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

על מנת לבצע את רוב הפעולות ב-node.js אנו קוראים למודולים. המודולים יכולים להגיע ב-core או להטען מבחוץ. אחד המודולים היותר חשובים הוא המודול שעוזר ל-node.js להתעסק עם הקבצים ושמו בישראל הוא fs – יעני file system 🙂 איך אנו קוראים למודולים? באמצעות require – אני ארחיב מאוד על מודולים בהמשך. אבל בוא בינתיים נרגע קצת ונסתכל על הקוד המאוד פשוט הזה:


var fs = require('fs');

filenames = fs.readdirSync(".");
for (i = 0; i < filenames.length; i++) {
    console.log(filenames[i]);
}

processId = process.getuid();
console.log(processId);

מה הקוד הזה עושה? לא צריך להיות מהנדס טילים כדי לדעת שמה שהוא עושה זה להדפיס את רשימת הקבצים שיש בתיקיה. בסופו של יום הוא מדפיס את ה-process id. מה הבעיה עם הקוד הזה? אין בעיה בכלל. מה הפלט שלו? על מנת לראות את הפלט שלו אני אשמור אותו כ:test_sync.js ואריץ אותו באמצעות nodejs test_sync.js. מה יצא לי בסוף מזה?


$ nodejs test.js 
test.js
test_sync.js
1000

מה אני מקבל פה? את רשימת הקבצים בתיקיה שלי (במקרה הזה test.js וכמובן test_sync.js) ואז מספר שמציין את ה-ProcessId. לא משהו שצריך להפיל אתכם.

מדובר פה בקוד סינכרוני – זה קוד שכל מי שמתכנת JS יותר מיום אמור להכיר. הבעיה היא (או יותר נכון היתרון האדיר של Node.js) שאנו אמורים לכתוב את הקוד כקוד א-סינכרוני. האמת היא שמודול fs הוא אחד המודולים הבודדים שמאפשרים לכתוב קוד סינכרוני. למה אנחנו אמורים לכתוב קוד אסינכרוני? כי קוד סינכרוני תוקע לנו את המערכת. אם נסתכל על הקוד שלעיל, אנו נראה שיש שם בת’כלס שתי פעולות – הדפסת הקבצים, שמותנית בקריאה של התיקיה שבה אנו נמצאים והדפסת ה-processId. כאשר אנו כותבים קוד סינכרוני אנחנו בעצם תוקעים את המערכת ולא מאפשרים לשאר הפעולות להעשות. התקיעה היא לא בהדפסה של שמות הקבצים אלא בהמתנה הארוכה ל-fs כדי שיקרא את רשימת הקבצים.

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

איך עושים את זה? באמצעות callbacks. זה סינטקס שאמור להיות מוכר מאוד לכל מי שהתעסק ב-jQuery בכלל וב-AJAX בפרט. מה שאנחנו עושים זה לקרוא ל-fs ואז לומר – ‘מר בחור, עד שתסיים עם הקריאה מה-fs ותשיג לי את כל המידע – תמשיך את הסקריפט ואל תחכה’. איך עושים את זה?


var fs = require('fs');

fs.readdir(".", function (err, filenames) {
    var i;
    for (i = 0; i < filenames.length; i++) {
        console.log(filenames[i]);
    }
});

processId = process.getuid();
console.log(processId);

הדבר הכי חשוב פה הוא להסתכל איך הפעולה של ה-fs.readdir בנויה. אני מעביר לה שני ארגומנטים – הראשון הוא הפרמטר שהיא צריכה (באיזה נתיב לחפש) – בדיוק כמו הקוד הסינכרוני. השני הוא פונקציה אנונימית חביבה שמקבלת שני ארגומנטים גם היא: err (לתקלות) ו-filenames) שזו התוצאה. הפונקציה האנונימית מכילה את ההדפסה של שמות הקבצים. את ההדפסה של ProcessId אני מבצע כרגיל.

איך הפלט יראה לפי דעתכם? אותו הדבר?
בוודאי שלא! הוא יראה ככה:


$ nodejs test.js 
1000
test.js
test_sync.js

מה השינוי לעומת הפלט של הקוד הסינכרוני? שההדפסה של ה-ProcessId מתבצעת קודם! למה? איך זה יכול להיות? הרי ההדפסה הארורה מופיעה במורד הקוד! ההסבר הוא שכפי שהסברתי קודם לכן – מדובר בקוד א-סינכרוני. ה-callback של fs מופעל רק כשה-fs מסיימת לקרוא את מערכת הקבצים – עד אז הקוד ממשיך כרגיל ואין לנו תקיעות של המערכת.

אם זה נראה לכם מסובך או לא מובן מספיק, הייתי מציע לכם לבדוק את jQuery ו-AJAX – שם בדיוק זה אותו הדבר. אנו מבצעים פעולה (GET באמצעות AJAX לצורך העניין) ומבצעים callback רק כשהתוצאה מגיעה מהשרת, לא לפני. הסינטקס הוא אותו סינטקס.

המהפך מחשיבה של קוד סינכרוני לקוד אסינכרוני היא לא פשוטה, אנחנו נמשיך לדבר על קוד אסינכרוני בהמשך. מדובר באחד הדברים החשובים ביותר ב-Node.js.

כדאי תמיד להשאר מעודכנים! הרשמו לעדכונים של האתר במייל! - המייל יישלח כל יום ראשון בעשר בבוקר ויכיל אך ורק את המאמרים שהתפרסמו באינטרנט ישראל. ללא ספאם, ללא הצפות, ללא בלגנים. אם יש לכם טלגרם, בדקו את ערוץ הטלגרם של האתר שבו אני מעדכן על פוסטים חדשים 🙂
למאמר הקודם בסדרת המדריכים על Node.js
למאמר הבא בסדרת המדריכים על Node.js

אהבתם? לא אהבתם? דרגו!

לא אהבתי בכלללא אהבתיבסדראהבתיאהבתי מאוד (14 הצבעות, ממוצע: 4.64 מתוך 5)

תגיות: פורסם בקטגוריה: Node.js

יאללה, שתפו :)

אל תשארו מאחור! יש עוד מה ללמוד!

7 comments on “מדריך Node.js: קוד אסינכרוני
  1. Assaf הגיב:

    ג’ים משך אותי ממש להתחלה…:)
    בהרצה האה סינכרונית אני מקבל את השגיאה הבאה:
    process.getuid is not a function
    ממה יכול להיות שנובע?

  2. אבי הגיב:

    הבנתי את העקרון של הפוסט,הכתיבה שלך בהירה ומובנת!
    אך משום מה זה אני מריץ את הקובץ והוא נותן לי הודעות שגיאה.
    ניסיתי להעלות צילום מסך אבל אי אפשר..
    אז אשמח אם תוכל לתת לי את המייל שלך כדי שאשלח אליך הודעה, אם זה בסדר מבחינתך..
    בעקרון הוא כותב לי כל מיני דברים, אבל נראה לי שהעיקרי שבהם הוא getid is not a function

    • רן בר-זיק הגיב:

      זה בגללי, או יותר נכון – זה בגלל מערכת ההפעלה חלונות שלא אוהבת את processId = process.getuid();
      אני אתקן את הדוגמה, אבל אפשר להשתמש ב:
      process.hrtime(); במקום. זה אמור לעבוד גם על חלונות.

  3. זושא הגיב:

    מקצועי וקליל, תודה

כתיבת תגובה

האימייל לא יוצג באתר.

רישום