قبلا در مقاله ای با عنوان آشنایی با انگولار سیگنال در مورد فیچر سیگنال توضیح دادم. در اون مقاله در مورد untracked حرفی نزدم. امروز تصمیم گرفتم بر اساس یک مسئله واقعی که دیروز در توسعه اپلیکیشن برام پیش اومده، در مورد فیچر untracked در انگولار سیگنال بنویسم.
نکته: من فقط قسمت هایی از کد رو نوشتم که به مشکل مربوطه. هر بخشی از این کد قسمتی از یک پازل بزرگتره و امکان تغییرشون نیست. دقت کنید که دنبال مُدل دیگه ای از پیاده سازی نیستیم.
فرض کنید یک سرویس داریم به اسم FirstService که یک سیگنال پابلیک تعریف کرده به اسم aList . این سیگنال قراره هر وقت یک لیست آبجکت از نوع A رو از API گرفت، اون رو در سیگنال ست کنه:
و یک سرویس داریم به اسم SecondService که خودش یک لیست از آبجکت های A داره . این سرویس منتظره دیتای جدید از FirstService برسه، لیست آبجکت هایی رو که گرفته فیلتر کنه و نتیجه رو به ابتدای لیستش اضافه کنه و سیگنال لیست نهایی رو برای بقیه بفرسته:
در انگولار سیگنال مفهومی هست به اسم context. طبق توضیحات سایت انگولار، effect callback نسبت به همه سیگنال هایی که داخلش صدا زده میشوند یا مقداری رو ست میکنند حساسه. تابع #consumeA در واقع داخل context مربوط به effect داره اجرا میشه. پس اجرای effect هم به خواندن سیگنال aList حساسه که در سرویس FirstService تعریف شده ، هم به خواندن سیگنال b حساسه که داخل سرویس SecondService تعریف شده، هم به صدا زدن تابع set از سینگال b.
اولین مشکلی که این کد داشت و کامپایلر در موردش خطا داد، این بود که کامپایلر به صورت پیش فرض اجازه نوشتن داخل سیگنال رو در context مربوط به effect نمیده. پس با فرض اینکه میدونستم دارم چی کار میکنم، اجازه نوشتن داخل سیگنال رو به effect callback دادم:
بعد به مشکل خیلی بدتری خوردم!!!
سیستم بعد از رسیدن اولین لیست از آبجکت های A ، هنگ میکرد. حدس زدم یک جایی تو سیستم به لوپ بی نهایت رسیدم. بعد از چند دقیقه جستجو فهمیدم چه اتفاقی افتاده.
سیگنال b در آخرین خط از تابع consumeA داره خودش رو مینویسم. در حالیکه در خط اول همین تابع داره خوانده میشه. این تابع داخل effect context هست و کدهاش داخل این context اجرا میشن. بنابر این هر بار که سیگنال b نوشته میشه، callback effect دوباره اجرا میشه و آخرین مقدار موجود در first signal خوانده میشه. دوباره consumeA صدا زده میشه و سیگنال b خوانده میشه. دوباره بعد از فیلتر ست میشه و این لوپ ادامه پیدا میکنه...
اینجاست که untracked به کار میاد و مشکل رو حل میکنه. در واقع من میخوام callback effect به سیگنال b وابسته نباشه و با تغییر سیگنال b صدا زده نشه. بنابر این سیگنالی رو که میخوام به effect غیرحساس کنم، داخل untracked تعریف می کنم:
در واقع برای غیرحساس کردن effect به سیگنال هایی که داخلش تعریف شده، اون ها رو داخل untracked صدا میکنیم: