نود جی اس ناهمزمان است و این بدان معنی است که در زمان اجرای وظایف و توابع خود، منتظر به پایان رسیدن بخش مسدود کننده (Blocking) نمی شود. این وظایف می تواند همانند عملیات ورودی/خروجی فایل، فراخوانی برخی RestAPI و انتظار برای نتیجه یا نوشتن داده ها در دیتابیس و غیره باشد. بلکه به جای انتظار، به سراغ وظیفه بعدی رفته و از کال بک ها استفاده کرده و به اجرای باقی دستورات و قسمتها ادامه می دهد. یک کال بک بطور ساده یک معادل غیرهمزمان برای یک تابع است که پس از اجرای یک وظیفه فراخوانی می شود. مفهوم کال بک باعث می شود اجرای برنامه هیچگاه بخاطر انتظار عملیاتی خاص، بلاک نشود و اجازه می دهد بقیه وظایف به کار خود ادامه دهند. دلیل نامگذاری توابع کال بک هم به این دلیل است که در برخی مقاطع زمانی، کال بک (Callback) خواهند شد (مثل زمانی که فردی به شما تماس می گیرد و شما نمی توانید جواب دهید و بعدا با وی تماس می گیرید). نود جی اس بطور وسیع و بی شمار از کال بک ها بهره می برد و تمام APIها در نود جی اس مفهوم کال بک را بخوبی پشتیبانی می کنند.
یکی از ویژگیهایی که وجه تمایز نود جی اس است، این است که از کدنویسی non-blocking استفاده می کند. اجازه دهید این موضوع را با نگاهی به تفاوتهای کدنویسی Blocking و Non-Blocking خدمت شما عزیزان ارائه دهیم:
به تصویر زیر دقت کنید. تفاوت سناریو های non-blocking و blocking و چگونگی اجرای هر کدام در زمان خواندن یک فایل و چاپ محتوای آن چگونه خواهد بود:
توضیحات بیشتر همراه با قطعه کدهای داده شده در زیر آمده است:
Blocking code: تابعی که اجرای آن تحت تاثیر توابع دیگر با وظایف دیگر است یا به عبارت ساده، توابعی که همزمانی طبیعی دارند و دستورهای آنها به نوبت اجرا می شود، تحت blocking code درمی آیند.
//Name of the File is : blocking-code.js var fs = require('fs'); //For calculating execution time var date1 = new Date(); var time_start = date1.getTime(); console.log("starting at: " + time_start); console.log("Let's start reading file"); //Name of the file to be read var filename = 'output.txt'; //Reading file synchronously var content = fs.readFileSync(filename); console.log('Content : ' + content); //For calculating execution time var date2 = new Date(); var time_end = date2.getTime(); console.log("finishing at: " + time_end); var execution_time = time_end - time_start; console.log("Time for execution: " + execution_time ); //Consider it some another task in queue console.log('Another task to be executed');
که اجرا و نتیجه اجرای آن به صورت زیر است:
>node blocking-code.js starting at: 1510699688357 Let's start reading file Content : Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. A enean massa. Cum sociis natoque pena.... ... ...Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent cong ue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan curs us velit. Vestibulum ante ipsum primis in finishing at: 1510699688374 Time for execution: 17 Another task to be executed
همانطور که می بینید، وظایفی منتظر می مانند تا عملیات خواندن فایل به پایان برسد و سپس اجرا می شوند. به همین دلیل این کد از نوع blocking است.
Non-Blocking Code: تابعی که اجرای آن تحت تاثیر بقیه توابع و وظایف نیست. به عبارت ساده تر، تابعی که طبیعت ناهمزمان دارد در این دسته بندی قرار میگیرد.
//Name of the file: non-blocking-code.js var fs = require('fs'); //For calculating execution time var date1 = new Date(); var time_start = date1.getTime(); console.log("{Check point 1} starting at: " + time_start); console.log("Let's start reading file"); //Name of the file to be read var filename = 'output.txt'; //Reading file asynchronously fs.readFile('output.txt', (err, data) => { if (err) throw err; console.log("Content : " + data); }); //For calculating execution time var date2 = new Date(); var time_end = date2.getTime(); console.log("{Check point 2} finishing at: " + time_end); var execution_time = time_end - time_start; console.log("Time for execution: " + execution_time ); //Consider it some another task in queue console.log('Another task to be executed');
اجرا و نتیجه اجرای قطعه کد بالا را ببینید:
>node non-blocking-code.js {Check point 1} starting at: 1510700249917 Let's start reading file {Check point 2} finishing at: 1510700249920 Time for execution: 3 Another task to be executed Content : Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Don ec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Done c pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo..... ... ...Phasellus leo dolor, tempus non, auctor et, hendrerit quis, nisi. Curabitur ligula sapien, tincidunt non, euismod vitae, posuere imperdiet, leo. Maecenas malesuada. Praesent cong ue erat at massa. Sed cursus turpis vitae tortor. Donec posuere vulputate arcu. Phasellus accumsan curs us velit. Vestibulum ante ipsum primis in
دو نکته مهم قابل ملاحظه در خروجی بالا وجود دارد:
کال بک ها اگر دارای سطح فراخوانی تودرتوی بالا باشند، باعث پیچیدگی می شوند و درک و عیب یابی آنها مشکل خواهد شد. جهنم کال بک گاهی به هرم مرگ هم شناخته می شود.
fxn1(function(){ fxn2(function(){ fxn3(function(){ fxn4(function(){ fxn5(function(){ fxn6(function(){ fxn7(function(){ fxn8(function(){ .... }); }); }); }); }); }); }); });
در درس امروز از سلسله دروس 30 روز با نود جی اس، با مفهوم کال بک آشنا شدیم. تفاوت کد blocking و non-blocking را متوحه شدیم و در نهایت راههایی برای فرار از جهنم کال بک بیان کردیم.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.