为什么不允许我违背承诺?
Why am I not allowed to break a Promise?
以下简单的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;
希望这是有道理的。
为什么你不能直接从外部keep/break Promise 或在 Thread Pool 上停止它的原因在 Jonathan 的评论中有解释。
Promise 的常见误用来自超时模式。
await Promise.anyof(
start { sleep 4; say "finished"; },
Promise.in( 1 )
);
say "moving on...";
sleep;
这将打印“完成”。当用户意识到他的下一个合乎逻辑的步骤是尝试杀死过时的 Promise。而解决它的唯一正确方法是让 Promise 意识到不再需要它的工作。例如通过定期检查一些共享变量。
如果您在 运行 上的 Promise 阻塞代码(例如数据库查询)太长并且您想从主线程终止它,事情就会变得复杂。这在 Promises 上是不可行的。您所能做的就是确保 Promise 在有限时间内 运行(例如在 MySQL 上通过在 运行ning 查询之前设置 MAX_EXECUTION_TIME)。然后你有选择:
- 咬咬牙耐心等待无极完成。例如,如果你真的必须在主线程中断开数据库。
- 或者您可以立即继续并让“已放弃”的 Promise 自行完成,而无需收到其结果。在这种情况下,您应该通过使用 Semaphore 或 运行 在专用的 ThreadPoolScheduler 上使用它们来控制这些 Promise 中有多少可以在后台堆叠。
以下简单的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;
希望这是有道理的。
为什么你不能直接从外部keep/break Promise 或在 Thread Pool 上停止它的原因在 Jonathan 的评论中有解释
Promise 的常见误用来自超时模式。
await Promise.anyof(
start { sleep 4; say "finished"; },
Promise.in( 1 )
);
say "moving on...";
sleep;
这将打印“完成”。当用户意识到他的下一个合乎逻辑的步骤是尝试杀死过时的 Promise。而解决它的唯一正确方法是让 Promise 意识到不再需要它的工作。例如通过定期检查一些共享变量。
如果您在 运行 上的 Promise 阻塞代码(例如数据库查询)太长并且您想从主线程终止它,事情就会变得复杂。这在 Promises 上是不可行的。您所能做的就是确保 Promise 在有限时间内 运行(例如在 MySQL 上通过在 运行ning 查询之前设置 MAX_EXECUTION_TIME)。然后你有选择:
- 咬咬牙耐心等待无极完成。例如,如果你真的必须在主线程中断开数据库。
- 或者您可以立即继续并让“已放弃”的 Promise 自行完成,而无需收到其结果。在这种情况下,您应该通过使用 Semaphore 或 运行 在专用的 ThreadPoolScheduler 上使用它们来控制这些 Promise 中有多少可以在后台堆叠。