مقدمه
در این درس یک معرفی ابتدایی از Node.js ارائه میشود تا قبل از هر چیز با ماهیت، کاربرد و موارد استفادهی آن آشنا شویم. به علاوه، خواهیم دید که چرا Node.js تا این حد بین توسعهدهندگان وب محبوب است.
آموزش Node.js و Express
در این درس یک معرفی ابتدایی از Node.js ارائه میشود تا قبل از هر چیز با ماهیت، کاربرد و موارد استفادهی آن آشنا شویم. به علاوه، خواهیم دید که چرا Node.js تا این حد بین توسعهدهندگان وب محبوب است.
Node.js یک پلتفرم برای تفسیر کد جاوااسکریپت و اجرای اپلیکیشنهاست. جاوااسکریپت در طول چند دههی اخیر با
پیشرفتها و بهبودهایی همراه بوده که این زبان را از یک زبان اسکریپتنویسی سمت کاربر به یک زبان برنامهنویسی
چندمنظوره تبدیل کرده که امکان کدنویسی سمت سرور و مدیریت دادهها را نیز ارائه میدهد.
بخشی از قدرت Node.js از آنجا ناشی میشود که این پلتفرم بر پایهی موتور جاوااسکریپتی V8 (مورد استفاده در
مرورگر Google Chrome) ساخته شده که نسبت به موتورهای جاوااسکریپتی مشابه از قدرت و سرعت تفسیر و اجرای بالاتری
برخوردار است.
تا قبل از معرفی Node.js کاربرد جاوااسکریپت در وب به کد سمت کاربر (client side) محدود بود؛ چون تنها محیط
میزبان برای کد جاوااسکریپت، مرورگرهای وب بودند. اما با معرفی Node.js به عنوان یک محیط میزبان مستقل از
مرورگر، امکان استفاده از این زبان در سمت سرور نیز فراهم شد و به این ترتیب، توسعهدهندگان میتوانند تنها با
تسلط بر یک زبان به نام جاوااسکریپت، اپلیکیشنهای وب کامل و پیشرفتهای ایجاد کنند. این در حالیست که تا قبل از
Node.js توسعهدهندگان وب برای کدتویسی سمت سرور باید از زبانهایی مانند PHP و پایتون و C# استفاده میکردند.
در مورد معماری Node.js باید بدانید که در این پلتفرم، یک ترِد (thread) واحد روی یک حلقه رویداد (event loop)
عمل میکند. ترد بستهای از توان محاسباتی و منابع مورد نیاز برای انجام یک کار برنامهریزیشده است. به طور
کلی، یک ترد مسئول شروع و تکمیل یک کار است و هر چه کارهای بیشتری نیاز به اجرای همزمان داشته باشند، تردهای
بیشتری مورد نیاز است. با این حال و بر خلاف اکثر نرمافزارها و پلتفرمهای دیگر، Node.js در هر لحظه تنها یک
کار را مدیریت میکند و فقط برای کارهایی که توسط ترد اصلی قابل مدیریت نیستند، از تردهای بیشتر استفاده میکند.
این فرایند ممکن است منطقی به نظر نرسد اما در اپلیکیشنهایی که به پردازشهای محاسباتی سنگین نیاز ندارند، این
ترد واحد میتواند بهسرعت تمام کارها را مدیریت و اجرا کند. سیکلهای حلقه رویداد Node.js برای همیشه در یک
حلقه تکرار میشود و به رویدادهای جاوااسکریپتی که توسط سرور برای اطلاع از یک کار جدید یا تکمیل یک کار ایجاد
میشوند، گوش میدهد.
با افزایش تعداد کارها، آنها در یک صف قرار میگیرند تا بهنوبت توسط حلقه رویداد پردازش شوند. با این حال، این
موضوعی نیست که ما هنگام کدنویسی آن را در نظر بگیریم، بلکه ما کد خودر را بر اساس قراردادهای async مینویسیم و
معماری Node.js در پشتصحنه، زمانبندی پردازش کارها را برای ما انجام میدهد. به همین دلیل است که Node.js برای
ایجاد اپلیکیشنهای realtime که دائماً در حال رد و بدل کردن داده هستند، محبوب شده است.
خلقه رویداد در Node.js مانند یک مدیر دفتر عمل میکند. نقش مدیر دفتر این است که به پیامهای ورودی رسیدگی کند
و کارها و وظایف مرتبط با دفتر را به کارمندان تخصیص دهد. مدیر دفتر ممکن است لیست بلندبالایی از کارها برای
تکمیل داشته باشد؛ از واگذاری کار ایجاد یک گزارش مالی تا پاسخگویی به تلفن و ترتیبدادن یک جشن. از آنجایی که
برخی کارها به زمان بیشتری نیاز دارند، منطقی نیست که انجام یک کار جدید به تکمیل یک کار جاری مشروط شود. برای
مثال، نباید پاسخگویی به یک تلفن به پایان فرایند آمادهسازی برای جشن موکول شود، بلکه بهتر است کار آمادهسازی
برای جشن متوقف شود، تلفن پاسخ داده شود و سپس، ادامه داده شود. حتی بهتر از آن، مدیر میتواند تلفن را پاسخ
دهد، تماسگیرنده را به کارمند دیگری وصل کند و به ادامهی کار قبلی بپردازد.
به طور مشابه، حلقه رویداد مجموعهای از کارها را مدیریت میکند در حالی که در هر لحظه فقط روی یک کار متمرکز
است اما در صورت لزوم، بین کارها سوئیچ میکند. در اکثر پلتفرمهای دیگر، کارهای ورودی به پراسسها (processes)
واگذار میشوند و برای هر کار یک حلقه رویداد جدید ایجاد میشود. اما این کار مثل اضافهکردن تعداد کارمندان در
یک فضای محدود است و با مسائل جدیدی همراه است که معمولاً به هزینه، توان محاسباتی و منابع مشترک مربوط است.
برای مثال، اگر دو کارمند به طور همزمان به استفاده از تلفن نیاز داشته باشند، تکلیف چیست؟
توجه داشته باشید که حلقه رویداد Node.js برای مدیریت تمام وظایف (tasks) خود به یک ترد واحد متکی است اما لزوماً از آن ترد برای اجرای کامل هر کار استفاده نمیکند. در واقع، Node.js طوری طراحی شده که وظایف بزرگتر را به کامپیوتر میزبان منتقل کند و کامپیوتر میزبان ممکن است تردها و پراسسهای جدیدی برای اجرای وظایف ایجاد کند. یک ترد بستهای اختصاصی از منابع کامپیوتر است که برای اجرای مجموعهای از دستورالعملهای مربوط به یک کار استفاده میشود. معمولاً کارهایی که توسط تردها انجام میشوند، ساده و سریع هستند. به همین دلیل، حلقه رویداد Node.js تنها به یک ترد نیاز دارد که نقش مدیریت وظایف را بر عهده دارد. تردها از طریق پراسسهای کامپیوتر در دسترس قرار میگیرند و بعضی از کارهای فشردهتر برای اجرا به پراسسهای خاص خود نیاز دارند. پراسس نیز بستهای از قدرت محاسباتی و منابع است که برای اجرای یک کار استفاده میشود؛ البته با این تفاوت که کارهایی که توسط پراسسها انجام میشوند، نسبت به کارهایی که توسط تردها انجام میشوند، بزرگتر هستند. برای اجرای یک ترد باید یک پراسس وجود داشته باشد و این به این معناست که هر برنامهی Node.js در پراسس مختص خود اجرا میشود. اگرچه Node.js میتواند تکترد (single threaded) باشد اما میتوانیم چندین نمونه از پراسسها را به صورت موازی داشته باشیم و وظایف و درخواستهای ورودی را پردازش کنیم. به همین دلیل است که Node.js مقیاسپزیری بالایی دارد. بنابراین، Node.js کارها را به صورت غیرهمزمان (async) برنامهریزی میکند و به جای اینکه برای هر کار پراسسهای جدیدی ایجاد کند، فقط در صورتی که نیاز باشد از تردها و پراسسهای اضافی استفاده میکند. در مجموع میتوان گفت که Node.js کار به حداقل رساندن تعداد پراسسهای همزمان را به بهترین نحو انجام میدهد.
برای کدنویسی Backend علاوه بر Node.js گزینههای دیگری هم قابل انتخاب است که هر یک از آنها مثل Node.js نقاط ضعف و قوتی دارند. برای مثال، میتوان از PHP یا پایتون و یا زبانهای استاتیکی مانند C# و جاوا بدین منظور استفاده کرد. اما در ادامه، دلایلی را که به Node.js برتری میدهند، ذکر میکنیم: