Perl6制作一个可观察的计时器

时间:2018-06-28 09:20:01

标签: concurrency observer-pattern perl6

我正在尝试使用计时器类编写观察者模式,该计时器类以给定间隔调用其订阅者。一直试图理解Perl6中的promises概念。

class Timer does Observable
{
    has Promise $!p;
    has Int $!interval;
    has Bool $!active = False;

    submethod BUILD(Int :$!interval) {}

    method start {
        $!p = Promise.start( {
            $!active = True;
            loop {
                sleep($!interval);
                @!action_listeners>>.actionPerformed(ActionEvent.new);
                if !$!active {$!p.keep}
            }
        });
    }

    method stop {
        $!active = False;
    }
}

观察者角色只是拥有一个带有订阅者的数组。当然,我应该有一种方法来更新角色中的所有订户。

role Observable {
    has ActionListener @!action_listeners;

    method addActionListener(ActionListener $al){
        @!action_listeners.push($al);
    }

    method removeActionListener{
        @!action_listeners.pop;
    }
}

ActionListener角色仅具有一个actionPerformed方法。 ActionEvent类可能不是必需的,目前只是一个空类。

role ActionListener
{
    method actionPerformed(ActionEvent $e) { ... }
}

从脚本运行:

my Subscriber $s = Subscriber.new;
my Timer $t = Timer.new(interval => 1);

$t.start;
$t.addActionListener($s);
$t.addActionListener(Subscriber.new);

.... #doing stuff that lasts for a while
$t.stop;

订户类实现ActionListener角色(具有一个称为actionPerformed的方法)。

尽管可以正常工作:在我调用计时器的stop方法之前,将调用订户的actionPerformed方法。虽然没有适当的方法来删除给定的订户。我还想知道是否存在一种更好的方式来保持/违反承诺,即从外部给定代码循环。

我基本上想知道我是否会错过Perl6的内置功能?我在重新发明轮子吗?

2 个答案:

答案 0 :(得分:8)

要进一步回答重新发明轮子的问题:您应该看看SupplySupplyObservable的Perl 6术语,而TapSubscription的Perl 6术语。

为了获得可观察到的以固定间隔调用订户的方法,可以使用the interval class method of the Supply type。您将在.tap调用的结果上调用.interval来注册一个代码块,只要Supply emit是一个值和{{1}的结果时就运行}调用是.tap对象,您可以用来关闭订阅。

如果您想了解更多有关耗材的信息,

These talk slides by Jonathan Worthington可能会很有趣。

答案 1 :(得分:6)

回答您的问题“我是在重新发明轮子吗?”。可能。

您实际上可以要求当前的ThreadPoolScheduler(又名$*SCHEDULER)提示一段要间隔运行的代码:

my $canceller = $*SCHEDULER.cue( { say $++ }, every => 0.2 );
sleep 2;
# 0 1 2 3 4 5 6 7 8 9
$canceller.cancel;
say "stopped";  # no numbers should be seen afterward
# stopped    
sleep 1;        # keep from exiting immediately

这不涉及任何Promise,因此,如果您的目标是更多地了解Promise,那么不是。如果要创建观察者模式,这可能是创建它的最简洁的方法。