بررسی نحوه عملکرد جاوا اسکریپت در پشت صحنه

یک مرور کلی از تمام اجزای اصلی که در اجرای کد جاوا اسکریپت دخیل هستند.همانطور که جاوا اسکریپت روز به روز محبوب‌تر می‌شود، تیم‌ها از پشتیبانی آن در سطوح مختلف در پشته (stack) خود استفاده می‌کنند - فرانت‌اند، بک‌اند، برنامه‌های هیبریدی، دستگاه‌های جاسازی شده (embedded devices) و موارد دیگر. هدف این مقاله بررسی عمیق‌تر جاوا اسکریپت و نحوه عملکرد واقعی آن است.بررسی کلیتقریباً همه قبلاً نام موتور V8 را به عنوان یک مفهوم شنیده‌اند و بیشتر مردم می‌دانند که جاوا اسکریپت تک نخ single-threaded است یا از صف برگشت تماس callback queue استفاده می‌کند.تعریف threaded نخ - رشته یا Thread کوچک‌ترین واحد اجرایی در سیستم عامل است. Thread‌ واحد اساسی اجرایی یا واحد اساسی در بهره‌برداری از CPU به حساب می‌آید. Thread یکی از مفاهیم مهم در سیستم‌های عامل محسوب می‌شود. Thread موجودیتی در درون یک پردازه (پروسه | Process) است که می‌تواند برای اجرا زمان‌بندی شود. یک برنامه تحت اجرا به عنوان یک Process شناخته می‌شود. هر برنامه ممکن است تعدادی پردازه مرتبط داشته باشد و هر پردازه می‌تواند دارای چند Thread باشد که این Threadها آن پردازه را اجرا می‌کنند. تمام Threadهای یک پردازه فضای آدرس مجازی و منابع سیستمی آن پردازه را با یکدیگر شریک می‌شوند.در این مقاله، تمام این مفاهیم را با جزئیات مرور خواهیم کرد و نحوه اجرای جاوا اسکریپت را توضیح خواهیم داد. با دانستن این جزئیات، می‌توانید برنامه‌های بهتر و غیر مسدودکننده‌ای non-blocking بنویسید که به‌درستی از APIهای ارائه‌شده استفاده می‌کنند.اگر با جاوا اسکریپت نسبتاً تازه کار هستید، این پست وبلاگ بنده به شما کمک می کند بفهمید که چرا جاوا اسکریپت در مقایسه با زبان های دیگر «عجیب» است. و اگر یک توسعه‌دهنده جاوا اسکریپت با تجربه هستید، امیدواریم بینش تازه‌ای در مورد نحوه عملکرد JavaScript Runtime که هر روز استفاده می‌کنید به شما بدهد.در این مقاله به کار داخلی internal working جاوا اسکریپت در محیط زمان اجرا run-time و مرورگر می پردازیم. این یک مرور کلی از تمام اجزای اصلی است که در اجرای کد جاوا اسکریپت دخیل هستند. در مورد اجزای زیر بحث خواهیم کرد:موتور جاوا اسکریپت JavaScript Engineمحیط زمان اجرا جاوا اسکریپت JavaScript Runtime Environmentپشته تماس The Call Stackهمزمانی و رویداد حلقه Concurrency and Event Loopبیایید با موتور جاوا اسکریپت شروع کنیم.موتور جاوا اسکریپت JavaScript Engineهمانطور که قبلاً شنیده اید، جاوا اسکریپت یک زبان برنامه نویسی تفسیر شده interpreted است. این بدان معنی است که کد منبع قبل از اجرا در کد باینری (همون 0 و 1) کامپایل نمی شود.پس چگونه رایانه شما می تواند بفهمد که با یک اسکریپت متن ساده چه کاری باید انجام دهید؟این کار برای یک موتور جاوا اسکریپت است. موتور جاوا اسکریپت به سادگی یک برنامه کامپیوتری است که کد جاوا اسکریپت را اجرا می کند. موتورهای جاوا اسکریپت در تمام مرورگرهای مدرن امروزی تعبیه شده است. هنگامی که فایل جاوا اسکریپت در مرورگر بارگذاری می‌شود، موتور جاوا اسکریپت هر خط از فایل را از بالا به پایین اجرا می‌کند (برای ساده‌تر شدن توضیحی که از بالا بردن در JS اجتناب می‌کنیم). موتور جاوا اسکریپت کد را خط به خط تجزیه می کند، آن را به کد ماشین تبدیل می کند و سپس آن را اجرا می کند.هر مرورگر موتور جاوا اسکریپت خود را دارد اما شناخته شده ترین موتور گوگل V8 است. موتور V8 گوگل کروم و همچنین Node.js که همان جاوا اسکریپت Runtime است را تامین می کند.موتور از دو جزء اصلی تشکیل شده است:Memory Heap - اینجا جایی است که تخصیص حافظه اتفاق می افتدCall Stack - این جایی است که فریم های پشته شما در هنگام اجرای کد شما قرار دارندهر موتور جاوا اسکریپت همیشه حاوی یک Call Stack و یک Memory Heap است. Call Stack جایی است که کد ما واقعاً اجرا می شود. سپس heap یک مخزن حافظه بدون ساختار است که تمام اشیاء objects مورد نیاز برنامه ما را ذخیره می کند.محیط زمان اجرا جاوا اسکریپت JavaScript Runtime Environmentتاکنون موتور جاوا اسکریپت را مورد بحث قرار داده ایم، اما موتور جاوا اسکریپت به صورت مجزا کار نمی کند. این برنامه در محیطی به نام JavaScript Runtime Environment همراه با بسیاری از اجزای دیگر اجرا می شود. JRE مسئول ایجاد ناهمزمان جاوا اسکریپت است. به همین دلیل است که جاوا اسکریپت قادر است DOM و یا شنوندگان رویداد را اضافه کند add event listeners و درخواست های HTTP را به صورت ناهمزمان انجام دهد.همچنین JRE را درست مانند ظرفی تصور که از اجزای زیر تشکیل شده است:JS EngineWeb APICallback Queue or message queueEvent TableEvent loopو سپس، ما event loop بسیار محبوب و callback queue را داریم.پشته تماس The Call Stackجاوا اسکریپت یک زبان برنامه نویسی تک رشته ای single threaded است، به این معنی که دارای یک Call Stack است. بنابراین می تواند یک کار را در یک زمان انجام دهد.همچنین Call Stack یک ساختار داده data structure است که اساساً مکان برنامه ما را ثبت می کند. اگر وارد یک تابع شویم، آن را در بالای stack قرار می دهیم. اگر از یک تابع برگردیم، از بالای stack خارج می شویم. این تمام کاری است که stack می تواند انجام دهد.بیایید یک مثال ببینیم. به کد زیر دقت کنید:function multiply(x, y) { return x * y; } function printSquare(x) { var s = multiply(x, x); console.log(s); } printSquare(5);هنگامی که موتور شروع به اجرای این کد می کند، Call Stack خالی خواهد بود. پس از آن مراحل به صورت زیر خواهد بود:هر ورودی در Call Stack را Stack Frame می گویند.اجرای کد روی یک رشته single thread می‌تواند بسیار آسان باشد، زیرا نیازی نیست با سناریوهای پیچیده‌ای که در محیط‌های چند رشته‌ای multi-threaded به وجود می‌آیند سر و کار داشته باشید - به عنوان مثال، بن‌بست‌ها deadlocks.اما اجرای روی یک رشته نیز کاملاً محدود است. از آنجایی که جاوا اسکریپت دارای یک Call Stack است.همزمانی و رویداد حلقه Concurrency and Event Loopچه اتفاقی می‌افتد وقتی فراخوانی‌های تابعی در Call Stack دارید که پردازش آنها زمان زیادی می‌برد؟ به عنوان مثال، تصور کنید که می‌خواهید با جاوا اسکریپت در مرورگر تغییر تصویر پیچیده (complex image transformation) انجام دهید.ممکن است بپرسید - چرا این یک مشکل است؟ مشکل این است که در حالی که Call Stack عملکردهایی برای اجرا دارد، مرورگر در واقع نمی تواند کار دیگری انجام دهد - در حال مسدود شدن است. این بدان معنی است که مرورگر نمی تواند رندر کند، نمی تواند کد دیگری را اجرا کند، فقط گیر کرده است. و اگر می‌خواهید رابط‌های کاربری سیال خوبی در برنامه خود داشته باشید، این مشکل ایجاد می‌کند.و این تنها مشکل نیست. هنگامی که مرورگر شما شروع به پردازش بسیاری از وظایف در Call Stack می کند، ممکن است برای مدت طولانی دیگر پاسخگو نباشد. و اکثر مرورگرها با ایجاد یک خطا، از شما می پرسند که آیا می خواهید صفحه وب را خاتمه دهید یا خیر، اقدام می کنند. منبع : medium