نود.جی.اس قهرمان – برنامه نویسی Async

نود.جی.اس قهرمان – برنامه نویسی Async

این سومین پست از سری آموزش Node Hero است – در این فصل ها یاد خواهید گرفت چطور از Node.js استفاده کنید و چطور با استفاده از آن محصولات نرم افزاری توسعه دهید.

در این فصل شما را با اصول برنامه نویسی ناهمگام (async) آشنا می سازم و نشان خواهم داد که async در جاوا اسکریپت و Node.js به چه شکل است.

فصل های گذشته و آینده:

  1. شروع کار بار Node.js
  2. استفاده از NPM
  3. درک مفهوم برنامه نویسی async [در حال خواندن آن هستید]
  4. ساخت اولین سرور Node.js
  5. دسترسی به دادهای درون دیتابیس
  6. برقراری ارتباط با API
  7. سازماندهی ساختاری پروژه
  8. احراز هویت کاربران
  9. تست نرم افزار Node.js
  10. اشکال زدایی Node.js
  11. امنیت برنامه
  12. انتقال برنامه Node.js به Host اشتراکی
  13. نظارت بر روی برنامه Node.js

برنامه نویسی همگام (Synchronous)

در برنامه نویسی سنتی اکثر عملیات ورودی و خروجی I/O بصورت synchronous رخ می دهد. به عنوان مثل Java را در نظر بگیرید، فرض کنید می خواهیم فایلی را با استفاده از جاوا بخوانیم، این عمل چیزی شبیه به تکه کد زیر خواهد بود:

چه اتفاقی در پشت صحنه رخ می دهد؟ ریسمان اصلی تا وقتی که فایل را نخوانده مسدود می ماند، به این معنی که هیچ عملیات دیگری در آن بین انجام نم شود. برای حل این مشکل و استفاده بهتر از CPU بهتر است این ریسمان ها را بطور دستی مدیریت کنیم.

حتی وقتی عملیات مسدود بیشتر شود، صف رویداد بدتر می شود:

آموزش طراحی سایت با Node.js

نوارهای قرمز نشان می دهد که وقتی پروسه در انتظار پاسخ عملیات خارجی است و مسدود شده، نوارهای مشکی نشان می دهد که کد شما در حال اجرا است، نوارهای سبز بقیه برنامه را نشان می دهد.

برای حل این مشکل، Node.js مدل برنامه نویسی asynchronous را معرفی نموده.

برنامه نویسی asynchronous در Node.js

I/O ناهمگام فرمی از پردازش ورودی/خروجی است که این امکان را می دهد تا دیگر پروسه ها منتظر به پایان رسدن پروسه ای نباشند و به کار خود ادامه دهند.

در مثال زیر پروسه خواندن فایل در Node.js را در روش های sync و async نشان می دهم، هدف از این مثال اجتناب از مسدود شدن برنامه است.

اجازه دهید یک مثال ساده را شروع کنیم – خواندن فایل به صورت sync در Node:

چه اتفاقی اینجا رخ می دهد؟ ما سعی داریم فایلی را با استفاده از ماژول fs بصورت sync بخوانیم. این کد همانطور که انتظارش را داریم کار می کند – متغیر content شامل محتوای فایل file.md خواهد بود. مشکلی که در این روش وجود دارد این است که Node.js تا وقتی که پروسه به پایان نرسیده است مسدود خواهد ماند – به این معنی که مطلقا هیچ کاری را در هنگام خواندن فایل نمی توان انجام داد.

حال بیایید ببینیم چطور می توان این مشکل را حل کنیم!

برنامه نویسی Async – همانگونه که حالا در جاوا اسکریپت می شناسیم – آنها را می توان همانند هر متغیری به دیگر توابع ارسال کرد. توابعی که بتوانند دیگر توابع را به عنوان آرگومان قبول کنند با نام توابع higher-order شناخته می شوند.

یکی از راحترین مثال ها برای توابع higher-order در زیر آمده است:

در مثال فوق ما تابعی را به تابع filter ارسال می کنیم. با این روش می توانیم منطق فیلتر خود را تعریف کنیم.

اینجاست که callback ها ایجاد شدند. اگر تابعی را به عنوان پارامتر به یک تابع دیگر ارسال می کنید می توانید پس از پایان کار از داخل تابع آن را فراخوانی کنید. نیازی به برگشت داده نیست، تنها کافیست تابع دیگری را با مقدارش فراخوانی کنید.

این به اصطلاح error-first نامیده می شوند که در هسته خود Node.js هستند -همچون بسیاری از ماژول هایی که در NPM وجود دارند، هسته ماژول  ها از آن استفاده می کنند.

نکاتی که باید به آنها توجه داشت:

  • رسیدگی به خطاها: به جای try-catch می توانید خطاها را در callback بررسی کنید
  • مقدار بازگشتی وجود ندارد: توابع async مقادیری را بازگشت نمی دهند، اما بجاش مقادیر به callbackها ارسال می شوند

اجازه دهید این فایل را کمی تغییر دهیم تا ببینیم این مثال چطور کار می کند:

خروجی این اسکریپت بصورت زیر است:

همانطور که مشاهده می کنید وقتی شروع به خواندن فایل می کنیم، پروسه همچنان ادامه دارد و برنامه، end of the file را چاپ می کند. callback ما تنها یک بار فراخوانی می شود و خواندن فایل به پایان می رسد. چطور همچین چیزی امکان دارد؟ Event-Loop را ببینید.

Event Loop

event-loop قلب نود.جی.اس / جاوا اسکریپت است – مسئول زمان بندی عملیات async است.

قبل اینکه عمیق تر به موضوع بنگریم، اجازه دهید مطمئن شویم برنامه نویسی رویداد-محور (event-loop) را درک کرده ایم.

برنامه نویسی رویداد-محور یک الگوی برنامه نویسی است که اقدامات کاربر (کلیک ماوس، فشار دادن کلید)، سنسور خروجی ها یا پیام ها را از برنامه ها / ریسمان های دیگری شناسایی می کند.

در عمل به این معناست که برنامه ها بر پایه eventها عمل می کنند.

همچنین همانطور که در فصل اول یاد گرفتیم، Node.js از دیدگاه توسعه دهندگان، تک ریسمانی (single-thread) است. به این معنی که نیازی نیست با ریسمان ها و هماهنگ سازی آنها سروکار داشته باشید. Node.js از این پیچیدگی ها بدور است. همه چیز بجز کد شما بصورت parallel اجرا می شود.

برای درک عمیق تر event loop ویدیو زیر را مشاهده کنید:

Async.js

برای جلوگیری از به اصطلاح به دام افتادن در Callback-Hell کاری که می توانید انجام دهید استفاده از async.js است.

Async.js به کنترل آسان و ساختار برنامه شما کمک می کند.

اجازه دهید یک مثال کوتاه از Async.js داشته باشیم، و آنگاه آن را با Promises بازنویسی کنیم.

تکه کد زیر آمار سه فایل را به دست گزارش می دهد:

Promises

شی Promises برای به تاخیر انداختن و محاسبات async استفاده می شود. Promises عملی را نشان می دهد که هنوز به پایان نرسیده است اما قول می دهد که در آینده انجام شود.

در عمل، مثال قبل را می توان به صورت زیر بازنویسی کرد:

البته که اگر از متدی استفاده می کنید که دارای رابط Promise است، می توان مثال Promise را درتعداد کد کمتر نوشت.

 

قدم بعدی: ساخت اولین سرور Node.js خود

در فصل بعدی، یاد خواهید گرفت چطور یک سرور HTTP را با نود.جی.اس درست کنید. در خبرنامه سایت عضو شوید تا از بروزرسانی بلاگ با خبر شوید.

اگر هر گونه سوال دارید دریغ نکنید و در زیر بپرسید.


  • سلام
    مرسی و ممنون از مطلب بسیار کاربردی و خوبی که قرار دادی و مخصوصاً اون فیلم مربوط به Async حرف نداشت.

  • وحید

    سپاس فراوان

  • پوریا

    بابون جان یعنی عشق میکنم آموزشاتو می‌خونم بعد اهنگ پیشنهادیتو نگاه میکنم. لایک داری‌ی‌ی‌ی‌ید!!!!

    • پاتریک درآواکیانس

      مرسی دوست عزیز. خوشحالم که راضی هستید 😉