Supply
是一种适合事件分发的机制,但与EventEmitter
不同的是,它没有直接的命名事件机制--部分原因是Raku已经有了大量的过滤和调度方法,这些方法可以重复使用.
最常见的方法是使用键入的消息:
class Start { }
class End {
has $.value
}
假设Supplier
分,我们可以排放以下物质:
my $supplier = Supplier.new;
$supplier.emit(Start); # Don't need an instance if there's no data
$supplier.emit(End.new(value => 42));
接收端为Supply
:
my $supply = $supplier.Supply;
通常,执行emits 的事务将Supplier
保留为私有,并返回Supply
,这只允许接收.
在接收端,我们有多种方法来处理事件.例如,我们可以最直接地将您的示例翻译为:
$supply.grep(Start).tap: {
say "started";
}
$supply.grep(End).tap: {
say "ended {.value}";
}
如果使用 struct 化的supply
或react
数据块,则为:
react {
whenever $supply.grep(Start) {
say "started";
}
whenever $supply.grep(End) {
say "ended {.value}";
}
}
或者,您可能更喜欢使用when
Match struct :
$supply.tap: {
when Start { say "started"; }
when End { say "ended {.value}"; }
}
这在 struct 化方法中也是类似的工作方式:
react {
whenever $supply {
when Start { say "started"; }
when End { say "ended {.value}"; }
}
}
或者,您可以编写多个调度 routine 并订阅这些 routine :
multi process(Start) {
say "started"
}
multi process(End (:$value)) { # Can destructure the message in the signature
say "ended $value"
}
$supply.tap(&process);
除了接收端方法的灵活性之外,另一个优点是类名中的拼写错误将在编译时被检测到,而字符串中的拼写错误--至少如果您不是在TypeScrip或类似的语言中--很可能要到很晚才会被注意到.