Light logo

شنونده‌ها

با اصول اولیه شنونده‌ها توی ReArch آشنا شو.

شنونده‌ها

توی ReArch دو نوع شنونده داریم:

  1. شنونده‌های موقتی که وقتی دیگه نیازی بهشون نیست به‌صورت دستی حذف می‌شن
  2. شنونده‌هایی که تا وقتی خود کانتینر زنده‌ست، زنده می‌مونن (مثلاً برای یه لاگر)

نوع اول شنونده از طریق متد listen که روی کانتینرها وجود داره مدیریت می‌شه،
و توی کانتینرها توضیح داده شده.
نوع دوم چیزیه که این صفحه بهش می‌پردازه.

برای پیاده‌سازی یه شنونده بلندمدت،
فقط کافیه یه کپسول جدید بسازی (با یه تغییر کوچیک—ادامه رو بخون)!
اولین تلاشت (که اشتباهه) ممکنه چیزی شبیه این باشه:

dart
/// یه کپسول شنونده که به یه سری کپسول دیگه گوش می‌ده.  
/// توجه کن به نوع بازگشتی `void`؛  
/// شنونده‌ها فقط به داده‌های دیگه گوش می‌دن و چیزی برنمی‌گردونن.  
/// هشدار: این (یه کم) اشتباهه! برای اطلاعات بیشتر ادامه رو بخون.  
void myListener(CapsuleHandle use) {
  print(use(foobarCapsule));
}

// توی تابع main() یا یه جای مشابه،  
// شنونده رو مقداردهی کن (که یه بار صداش می‌کنه):  
container.read(myListener);                                    // فقط دارت  
CapsuleContainerProvider.containerOf(context).read(myListener) // فلاتر

اما کد بالا اون‌طور که انتظار داری کار نمی‌کنه؛
شنونده یه بار فراخوانی می‌شه،
ولی دیگه هیچ‌وقت دوباره فراخوانی نمی‌شه.
داره چی می‌گذره؟

نکته کلیدی اینجاست که myListener از یه اثر جانبی (print()) استفاده می‌کنه
که ReArch ازش خبر نداره چون از طریق یه اثر use.xyz ثبت نشده.
داخلاً، ReArch یادش می‌مونه که کدوم کپسول‌ها از اثرات جانبی استفاده می‌کنن و از این اطلاعات برای فعال کردن
بهینه‌سازی‌های مهمی استفاده می‌کنه، به‌خصوص جمع‌آوری زباله ایدمپوتنت (idempotent garbage collection).
به‌طور خلاصه، توی مثال بالا،
وقتی foobarCapsule داده جدید منتشر می‌کنه،
myListener به‌صورت خودکار حذف می‌شه (به‌جای اینکه بازسازی بشه) چون هیچ تقاضایی نداره.
یه کپسول وقتی تقاضا داره که خودش یا یکی از وابسته‌هاش یه اثر جانبی ثبت کنه
(که شامل گوش دادن توسط یه ویجت که بخشی از UI هست هم می‌شه).

پس راه‌حل اینجا ساده‌ست: چون توی myListener از یه اثر جانبی استفاده می‌کنیم
که ReArch ازش خبر نداره، بیایم به ReArch بگیم که داریم از یه اثر جانبی استفاده می‌کنیم!
می‌تونی هر اثر جانبی تصادفی‌ای رو ثبت کنی،
ولی یه اثر جانبی no-op داخلی وجود داره که یه کپسول رو به‌عنوان شنونده اعلام می‌کنه
(و چون یه اثر جانبیه، جمع‌آوری زباله رو غیرفعال می‌کنه).

dart
/// نسخه اصلاح‌شده شنونده که یه اثر جانبی ثبت می‌کنه  
/// تا به‌صورت خودکار حذف نشه.  
void myListener(CapsuleHandle use) {
  use.asListener();
  print(use(foobarCapsule));
}

// و در نهایت شنونده رو یه جایی نزدیک شروع اپلیکیشنت مقداردهی کن.  
container.read(myListener);                                    // فقط دارت  
CapsuleContainerProvider.containerOf(context).read(myListener) // فلاتر

On this page