如何解决为什么不允许我违反承诺?
以下简单的Promise誓言,不允许我破坏。
my $my_promise = start {
loop {} # or sleep x;
'promise response'
}
say 'status : ',$my_promise.status; # status : Planned
$my_promise.break('promise broke'); # Access denied to keep/break this Promise; already vowed
# in block <unit> at xxx line xxx
那是为什么?
解决方法
因为誓言 被誓言,所以您无法更改它:只有真正具有誓言的东西才能打破诺言。这就是vow
功能的目的。
您要通过兑现承诺来实现什么?是否要停止在start
块内完成的工作?打破承诺不会做到这一点。并且vow
机制已显式添加,以防止您认为它会以某种方式停止start
块内的工作。
如果要使start
块中的工作可被中断,则需要添加某种需要定期检查的信号量,例如:
my int $running = 1;
my $my_promise = start {
while $running {
# do stuff
}
$running
}
# do other stuff
$running = 0;
await $my_promise;
希望这很有道理。
,Jonathans评论中here解释了为什么您不能直接从外部保留/破坏Promise或在线程池上停止它的原因。
常见的对Promises的误用来自超时模式。
await Promise.anyof(
start { sleep 4; say "finished"; },Promise.in( 1 )
);
say "moving on...";
sleep;
此将打印“完成”。当用户意识到对他而言,下一个合理的步骤是尝试杀死过时的Promise。解决该问题的唯一正确方法是让Promise意识到不再需要其工作。例如,通过定期检查一些共享变量。
如果Promise上的阻塞代码(例如数据库查询)运行了太长时间,并且您想从主线程终止它,则事情将变得复杂。这在Promises上不可行。您所要做的就是确保Promise将在有限的时间内运行(例如,在运行查询之前,通过设置MAX_EXECUTION_TIME在MySQL上)。然后您可以选择:
- 您可以磨牙,耐心等待Promise完成。例如,如果您确实必须断开主线程中的数据库。
- 或者您可以立即继续前进,让“被遗弃”的Promise自己完成,而不会收到结果。在这种情况下,您应该通过使用信号量或在专用ThreadPoolScheduler上运行它们来控制可以在后台堆叠的那些Promise。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。