请考虑以下代码。为什么输出的是“ BABABA”而不是“ AAABAA” /“ AABAAAB”?这两个供应源不应该并行运行,并且当其中任何一个事件发生时立即火起来吗?
my $i = 0;
my $supply1 = supply { loop { await Promise.in(3); done if $i++> 5; emit("B"); } };
my $supply2 = supply { loop { await Promise.in(1); done if $i++> 5; emit("A"); } };
react
{
#whenever Supply.merge($supply1, $supply2) -> $x { $x.print }
whenever $supply1 -> $x { $x.print };
whenever $supply2 -> $x { $x.print };
}
Run Code Online (Sandbox Code Playgroud)
当我们订阅一个supply块时,该块的主体supply立即运行以设置订阅。在此过程中,没有引入并发。如果我们想要的话,我们需要要求它。
最佳解决方案取决于示例与您正在做的事情的距离。如果非常接近-并且您希望emit每个时间间隔都进行赋值-那么解决方案是Supply.interval改用:
my $i = 0;
my $supply1 = supply { whenever Supply.interval(3, 3) { done if $i++ > 5; emit("B"); } };
my $supply2 = supply { whenever Supply.interval(1, 1) { done if $i++> 5; emit("A"); } };
react {
whenever $supply1 -> $x { $x.print };
whenever $supply2 -> $x { $x.print };
}
Run Code Online (Sandbox Code Playgroud)
只需设置一个订阅即可退出设置,从而获得所需的输出,但是您确实在上进行了数据竞争$i。
更通用的模式是做任何使循环在设置步骤之外发生的事情。例如,我们可以使用a容器Promise来“ thunk”它:
my constant READY = Promise.kept;
my $i = 0;
my $supply1 = supply whenever READY {
loop { await Promise.in(3); done if $i++> 5; emit("B"); }
}
my $supply2 = supply whenever READY {
loop { await Promise.in(1); done if $i++> 5; emit("A"); }
}
react {
whenever $supply1 -> $x { $x.print };
whenever $supply2 -> $x { $x.print };
}
Run Code Online (Sandbox Code Playgroud)
这有帮助,因为a的结果Promise将supply通过线程池调度程序传递到块,从而将whenever包含循环的内容强制执行到自己的预定任务中。
这不是特别漂亮,但是如果我们定义一个函数来做到这一点:
sub asynchronize(Supply $s) {
supply whenever Promise.kept {
whenever $s { .emit }
}
}
Run Code Online (Sandbox Code Playgroud)
然后,原始程序只需要添加两个调用即可:
my $i = 0;
my $supply1 = supply { loop { await Promise.in(3); done if $i++> 5; emit("B") } }
my $supply2 = supply { loop { await Promise.in(1); done if $i++> 5; emit("A") } }
react {
whenever asynchronize $supply1 -> $x { $x.print }
whenever asynchronize $supply2 -> $x { $x.print }
}
Run Code Online (Sandbox Code Playgroud)
为了使其按需工作。可以说,这样的东西应该作为内置提供。
根据Channel其他解决方案的建议,也可以使用,这取决于当前合适的问题。这个问题与实际问题有点过抽象,我无法说。该解决方案处于Supply范式之内,在这种意义上更为整洁。