آشنایی با انگولار سیگنال ، فیچر جذاب نسخه ۱۶

مدت ها بود که برنامه نویسان انگولار منتظر آمدن سیگنال بودند. بالاخره این اتفاق افتاد و از نسخه ۱۶ انگولار میتوانیم از این ویژگی استفاده کنیم. سادگی و موثربودن سیگنال در مراقبت از تغییرات مقادیر باعث جذابیت این فیچر تازه وارد شده است.سیگنال چیست؟با یک مثال ساده شروع کنیم.اگر بخواهیم مقدار x را تغییر دهیم، می بینیم که مقدار z تغییری نمیکند:حالا اگر همین متغیرها را با سیگنال تعریف کنیم، میتوانیم مقدار z را بر حسب تغییرات x و y ، تغییر دهیم:حالا بیایم یه کم در مورد مثال بالا بیشتر صحبت کنیم. از نظر فنی x، y و z در واقع تابع هایی هستند که هیچ پارامتر ورودی ندارند و هر موقع آنها را صدا کنیم، آخرین وضعیت خود را بر میگردانند. مقدار اولیه x عدد ۵ و مقدار اولیه y عدد ۳ است. z هم بر اساس تغییرات x و y خود را تغییر میدهد.تعریف سیگنال:سیگنال در واقع یک wrapper اطراف متغیر است که وقتی مقدار متغیر تغییر کند، مصرف کننده ها (consumers) را باخبر کند. سیگنال میتواند هر نوع متغیری را، از primitive ها تا متغیرهایی با ساختارهای پیچیده ، در بر بگیرد. تغییرات توسط یک تابع به اطلاع مصرف کننده ها میرسد. سیگنال ها به دو صورت writable (اعمال تغییر مستقیم) و computed (اعمال تغییر غیر مستقیم) هستند.سیگنال های writable :شما می توانید با فراخوانی تابع signal به همراه مقدار اولیه، یک سیگنال writable بسازید تا هر زمان لازم شد، مقدار آن را مستقیما تغییر دهید:اگر میخواهید مقدار جدیدی را جایگزین کنید و به مقدار فعلی کاری ندارید، میتوانید از تابع set استفاده کنید:همچنین میتوانید برای گرفتن مقدار فعلی و تغییر آن به مقدار جدید از تابع update استفاده نمایید:اگر متغیر شما یک آبجکت، آرایه یا هر مقداری پیچیده دیگری است و میخواهید بخشی از آن را تغییر دهید، می توانید از تابع mutate استفاده نمایید:سیگنال های writable از نوع WritableSignal هستند.سیگنال های computed :سیگنال های computed در واقع سیگنال هایی هستند که تغییرات سیگنال های دیگر را مشاهده کرده و مقدار خود را تغییر میدهند.مقدار سیگنال doubleCount به متغیری بستگی دارد که سیگنال count برمیگرداند. هر زمان که سیگنال count تغییر کند، doubleCount هم تغییر کرده و مصرف کنندگان خود را مطلع میکند.سیگنال doubleCount پس از ساخته شدن، مقدار خود را تا زمانی که خوانده نشود، محاسبه نمیکند. یک بار که خوانده شد، مقدار خود را cache میکند و تا زمانی که سیگنال cache تغییر نکند، از همان cache استفاده میکند و خود را تغییر نمی دهد.در نتیجه این سیاست، استفاده از سیگنال های computed برای محاسبات و تغییر در ساختارهای داده سنگین، هزینه کمی به سیستم تحمیل میکند.در سیگنال های computed شما نمی توانید مستقیما توابعی مانند set را صدا بزنید و زمان کامپایل به شما خطا برمیگرداند.تابع effect:تابع effect توسط یک lambda expression، تغییرات رخ داده در سیگنال ها را مصرف میکند:من به شخصه از تابع effect برای هماهنگی متغیرهایی که در تمپلت جهت نمایش و یا در سرویس های دیگر نیاز داشته ام استفاده کردم. باید مراقب باشیم که تغییرات effect و change detection برنامه را دچار لوپ بی نهایت تغییرات نکنند. به همین دلیل استفاده از set در lambda expression هنگام رجیستر کردن افکت ممنوع شده است.برای رجیستر کردن افکت توسط تابع effect نیاز به injection context انگولار داریم. راحت ترین راه، صدا کردن تابع effect در constructor کلاس های کامپوننت ها و سرویس هاست.اگر بخواهیم افکت را خارج از constructor رجیستر کنیم، نیاز داریم که ابتدا Injector را به کلاس وارد کنیم و در ورودی دوم تابع افکت، آن را پاس بدهیم:افکت را در هر context خاصی که تعریف کرده باشیم، با از بین رفتن آن context افکت هم به صورت خودکار از بین میرود. مثلا اگر افکت را در یک کامپوننت تعریف کرده باشیم، با از بین رفتن آن کامپوننت، افکت تعریف شده داخل آن هم از بین میرود. نیازی نیست که مراقب از بین رفتن افکت باشیم و این کار ما را ساده تر میکند.صحبت پایانیاستفاده از سیگنال و افکت مراقبت از تغییرات را کم هزینه تر ، ساده تر و سریع تر میکند. به دلیل اینکه این کار را با توابع بدون پارامتر انجام میدهد سرعت و راحتی زیادی به پیاده سازی میدهد. اما باید دقت کنیم که جای RxJS را نمیگیرد، زیرا امکاناتی که RxJS ارائه میدهد به مراتب گسترده تر از سیگنال است. میتوان این دو قابلیت را کنار یکدیگر استفاده کرد و برنامه های پایدارتر و موثرتری ساخت.:)