Курс по Raku / Функционално, паралелно, реактивно и уеб програмиране / Реактивно програмиране / Живи supply и supply при поискване

Живи supply в действие

Понеже живият поток излъчва към онези включвания, които слушат в момента, няколко слушателя могат да следят една и съща струя наведнъж — и всеки е свободен да се присъедини или да си тръгне когато поиска. Тук двама слушатели наблюдават поток от събития: log, който записва всичко, и alert, който се присъединява по-късно и си тръгва по-рано.

my $supplier = Supplier.new;
my $events   = $supplier.Supply;

my $log = $events.tap(-> $v { say "log:   $v" });    # първият слушател се присъединява
$supplier.emit('start');

my $alert = $events.tap(-> $v { say "alert: $v" });  # присъединява се втори слушател
$supplier.emit('warning');
$supplier.emit('all clear');

$log.close;                                          # първият слушател си тръгва
$supplier.emit('stop');

Това отпечатва:

log:   start
log:   warning
alert: warning
log:   all clear
alert: all clear
alert: stop

Жизненият цикъл на двете включвания се подрежда така — 🟢 отбелязва присъединяване, 🔴 — тръгване, а ✅ — всяка стойност, която включването действително получава:

Стъпка log alert
$events.taplog 🟢 присъединява се
emit 'start' ✅ start
$events.tapalert 🟢 присъединява се
emit 'warning' ✅ warning ✅ warning
emit 'all clear' ✅ all clear ✅ all clear
$log.close 🔴 тръгва си
emit 'stop' ✅ stop

Празна клетка означава, че това включване не е слушало, когато стойността е излязла. Проследете хронологията:

  • .tap връща обект Tap — дръжката, която пазите, за да управлявате точно този абонамент.
  • start е подадено, докато слуша само log, така че само log го вижда. Това е пак правилото на живия поток: alert се присъедини след start, а живият поток не пуска миналото наново, така че alert никога не го вижда.
  • warning и all clear са подадени, докато са включени и двете, така че всяка стойност достига и до двете — в реда, в който включванията са се абонирали: първо log, после alert.
  • Извикването на $log.close напуска потока. Оттам нататък log не получава нищо, така че последното stop достига само до alert.

Две неща за отнасяне. Първо, един жив поток може да се разклони ветрилообразно към много независими включвания наведнъж. Второ, всяко включване е свой собствен абонамент със свой живот: задръжте обекта Tap, който .tap връща, и ще можете да прекратите точно този слушател с .close, без да безпокоите останалите.

Навигация в курса

Живи supply   |   Две свързвания


💪 Или преминете направо към упражненията в този раздел.