یکی از رایج ترین کارهایی که در انگولار انجام میدیم، Reactive Programming به کمک RxJS است. یادمه اوایل که آشنایی زیادی با Angular 2 و RxJS نداشتم و برام تازگی داشتند، برای هر Observable یک Subscription تعریف میکردم :)) همه Subscription ها رو جدا جدا ذخیره میکردم و در هوک ngOnDestroy همه رو unsubscribe میکردم:
بعدا که با RxJS بیشتر آشنا شدم، یک متغیر Subscription تعریف میکردم. همه Observable ها رو داخلش اضافه میکردم و در هوک ngOnDestroy ، متغیر Subscription رو unsubscribe میکردم. اینطوری کد کمتر و بهینه تری می نوشتم:
این کد اشتباه نیست و کاملا درست و عالی کار میکنه. هیچ مشکلی هم نداره. ولی یک کم باد کرده!! یکی از امکانات نسبتا جدیدتری که انگولار در اختیار ما قرار داده، async pipe هست که به کمکش نیازی به Subscription و استفاده از هوک ngOnDestory نداریم. چون خودش subscription رو به طور خودکار موقع از بین رفتن کامپوننت، unsubscribe میکنه. فعلا خلاصه ترین و ساده ترین روشی که میتونیم از Observable ها استفاده کنیم اینطوریه:
و داخل کامپوننت هم اینطوری دیتاها رو با async pipe نمایش میدیم:
اما یک نکته ای هست. همیشه دیتاها رو به همون صافی و پوست کندگی که از سرویس میگیریم به تمپلت منتقل نمیکنیم. بعضی موقع ها نیاز پیدا میکنیم که ساختار دیتا رو تغییر بدیم. یا مثلا بعد از گرفتن دیتا، یک تابع دیگه ای رو هم صدا کنیم ( کار دیگه ای هم انجام بدیم ).
در این موارد چه کار کنیم؟
راه حلش استفاده از pipe، map، tap یا سایر عملگرهای RxJS هست. مثال زیر رو مرور کنیم. ما میخوایم ادرس رو داخل تمپلت به صورت string نمایشش بدیم. مقدار اولیه آدرس رو هم جداگانه نگه داری کنیم. و بعد از اینکه مقدارش رو گرفتیم کاری رو انجام بدیم ( تابع #afterAddressLoaded رو صدا کنیم ). همه این کارها رو به کمک اپراتورهای RxJS به صورت زیر انجام میدیم ( به تغییر تایپ متغیر address$ توجه کنید ) :
می بینیم که به کمک اپراتور های pipe و map و tap در RxJS این کارها رو انجام دادیم و نه نیازی به Subscription داشتیم و نه unsubscript و ...
خلاصه کلام اینکه برای استفاده از Observable ها در کامپوننت نیازی به تعریف Subscription، استفاده از هوک ngOnDestory و unsubscribe کردن دیتاها نداریم. میتونیم کدی به مراتب تمیزتر، کوچک تر و مرتب تر بنویسیم.
موفق باشید :)