آموزش جاوا اسکریپت پیشرفته : معرفی workerها
در این مقاله، به معرفی workerها خواهیم پرداخت که به شما امکان میدهند برخی از وظایف را در یک thread جداگانه اجرا کنید.
در مقاله اول جاوا اسکریپت ناهمزمان، دیدیم که وقتی یک وظیفه همگام طولانی مدت در برنامه خود دارید چه اتفاقی میافتد - کل پنجره کاملاً بیپاسخ میشود. اساساً، دلیل این امر این است که برنامه تکرشتهای است. یک رشته، دنباله ای از دستورالعملهایی است که یک برنامه دنبال میکند. از آنجا که برنامه از یک رشته تشکیل شده است، فقط میتواند یک کار را در یک زمان انجام دهد: بنابراین اگر منتظر بازگشت فراخوانی همگام طولانی مدت ما باشد، نمیتواند کار دیگری انجام دهد.
کارگرها به شما این امکان را میدهند که برخی از وظایف را در یک رشته متفاوت اجرا کنید، بنابراین میتوانید وظیفه را شروع کنید، سپس با پردازشهای دیگر (مانند مدیریت اقدامات کاربر) ادامه دهید.
یکی از نگرانیهای همه اینها این است که اگر چندین رشته بتوانند به دادههای مشترک یکسان دسترسی داشته باشند، ممکن است آنها آن را به طور مستقل و غیرمنتظره (نسبت به یکدیگر) تغییر دهند. این میتواند باعث ایجاد اشکالاتی شود که یافتن آنها دشوار است.
برای جلوگیری از این مشکلات در وب، کد اصلی و کد کارگر شما هرگز به متغیرهای یکدیگر دسترسی مستقیم ندارند و فقط در موارد بسیار خاص میتوانند دادهها را واقعاً "به اشتراک" بگذارند. کارگرها و کد اصلی در دنیای کاملاً جداگانهای اجرا میشوند و فقط با ارسال پیام به یکدیگر تعامل دارند. به طور خاص، این بدان معناست که کارگرها نمیتوانند به DOM (پنجره، سند، عناصر صفحه و غیره) دسترسی داشته باشند.
سه نوع کارگر مختلف وجود دارد:
کارگرهای اختصاصی
کارگرهای اشتراکی
کارگرهای خدماتی
در این مقاله، نمونهای از نوع اول کارگر را بررسی خواهیم کرد، سپس به طور خلاصه دو نوع دیگر را مورد بحث قرار خواهیم داد.
قرار است از یک worker برای اجرای محاسبه اعداد اول استفاده کنیم، تا صفحه ما نسبت به اقدامات کاربر پاسخگو بماند.
تولیدکنندهی همزمان عدد اول
بیایید ابتدا نگاهی دیگر به کد جاوا اسکریپت در مثال قبلی خود بیندازیم:
در این برنامه، پس از اینکه تابع را فراخوانی میکنیم، برنامه کاملاً از کار میافتد.
تولیدکنندهی عدد اول با worker
برای این مثال، با ایجاد یک کپی محلی از کد زیر کنید و دو فایل خالی جاوا اسکریپت را بسازید و شروع کنید. سه فایل در این دایرکتوری وجود دارد:
index.html
main.js
generate.js
فایل "index.html" از قبل تکمیل شده:
فایلهای "main.js" و "generate.js" خالی هستند. ما قصد داریم کد اصلی را به "main.js" و کد worker را به "generate.js" اضافه کنیم.
بنابراین ابتدا میتوانیم ببینیم که کد worker در یک اسکریپت جداگانه از کد اصلی نگهداری میشود. همچنین با نگاه به "index.html" در بالا میتوانیم ببینیم که فقط کد اصلی در یک عنصر گنجانده شده است.
حالا کد زیر را در "main.js" کپی کنید:
ابتدا، ما با استفاده از سازندهی یک worker ایجاد میکنیم. ما یک URL به آن ارسال میکنیم که به اسکریپت worker اشاره میکند. به محض ایجاد worker، اسکریپت worker اجرا میشود.
در مرحلهی بعد، مانند نسخهی همگام، یک کنترلکنندهی رویداد کلیک به دکمهی "Generate primes" اضافه میکنیم. اما اکنون، به جای فراخوانی تابع ، با استفاده از پیامی را به worker ارسال میکنیم. این پیام میتواند یک آرگومان دریافت کند و در این حالت، ما یک شیء JSON حاوی دو ویژگی ارسال میکنیم:
command: رشتهای که مشخص میکند چه کاری را میخواهیم worker انجام دهد (در صورتی که worker ما بتواند بیش از یک کار انجام دهد)
quota: تعداد اعداد اول برای تولید.
در مرحلهی بعد، یک کنترلکنندهی رویداد message به worker اضافه میکنیم. این کار برای این است که worker بتواند به ما بگوید چه زمانی کار تمام شده است و هر دادهی حاصل را به ما منتقل کند. کنترلکنندهی ما دادهها را از ویژگی data پیام میگیرد و آن را در عنصر خروجی مینویسد (دادهها دقیقاً مشابه quota هستند، بنابراین این کمی بیمعنی است، اما اصل را نشان میدهد).
در نهایت، ما رویداد کلیک را برای دکمه "بارگیری مجدد" پیادهسازی میکنیم. این دقیقاً مشابه نسخه همگام است.
حالا برای کد worker. کد زیر را در "generate.js" کپی کنید:
به یاد داشته باشید که این به محض اینکه اسکریپت اصلی، worker را ایجاد میکند، اجرا میشود.
اولین کاری که worker انجام میدهد، شروع به گوش دادن به پیامهای اسکریپت اصلی است. این کار را با استفاده از انجام میدهد که یک تابع سراسری در worker است. در داخل کنترلکننده رویداد پیام، ویژگی داده رویداد شامل یک کپی از آرگومان ارسال شده از اسکریپت اصلی است. اگر اسکریپت اصلی دستور generate را ارسال کرده باشد، را فراخوانی میکنیم و مقدار quota را از رویداد message ارسال میکنیم.
تابع درست مانند نسخه همزمان است، با این تفاوت که به جای بازگرداندن یک مقدار، وقتی کارمان تمام شد، یک پیام به اسکریپت اصلی ارسال میکنیم. برای این کار از تابع استفاده میکنیم که مانند یک تابع سراسری در worker است. همانطور که قبلاً دیدیم، اسکریپت اصلی به این پیام گوش میدهد و DOM را هنگام دریافت پیام بهروزرسانی میکند.
برای اجرای این سایت، باید یک وب سرور محلی اجرا کنید، زیرا URLهای مجاز به بارگیری workerها نیستند. برای راه اندازی چگونگی راه اندازی سرور به ماژول ابزارها مراجعه کنید. با انجام این کار، باید بتوانید روی «تولید اعداد اول» کلیک کنید و صفحه اصلی شما واکنشگرا باقی بماند.
کارگر (worker) که ما تازه ایجاد کردیم، چیزی بود که کارگر اختصاصی (dedicated worker) نامیده میشود. این بدان معناست که توسط یک نمونه اسکریپت واحد استفاده میشود.
با این حال، انواع دیگری از کارگرها نیز وجود دارند:
کارگران مشترک میتوانند توسط چندین اسکریپت مختلف که در پنجرههای مختلف اجرا میشوند، به اشتراک گذاشته شوند.
کارگران سرویس مانند سرورهای پروکسی عمل میکنند و منابع را ذخیره میکنند تا برنامههای وب بتوانند در صورت آفلاین بودن کاربر کار کنند. آنها یک جزء کلیدی از برنامههای وب پیشرونده (PWA) هستند.