我如何使 Raku 中的承诺超时?
How can I timeout a promise in Raku?
我知道我可以安排 Promise
在给定的时间内保存
my $promise = Promise.in($seconds);
但是我怎样才能安排它坏掉呢?具体来说,我正在考虑一个 "timeout" 的承诺,这样它就可以保留一定的时间,否则就会失败。
我可以用另一个 Promise
来做这个,就像这样:
my $promise = Promise.new;
...
Promise.in($seconds).then: { $promise.break };
但这感觉有点……浪费。有更好的方法吗?
一个常见的模式是这样写:
await Promise.anyof($the-promise, Promise.in(10));
if $the-promise {
# it finished ahead of the timeout
}
else {
# it timed out
}
这并没有表现为损坏的 Promise
,尽管这并非全是坏事(因为无论如何在许多情况下您都需要区分取消与错误,因此您仍然需要进行一些匹配关于异常类型)。此因式分解还有一个优点,即 $the-promise
不必是您有权访问 keep/break.
的一个因式分解
也可以这样总结:
class TimedOut is Exception {}
sub timeout($promise, $time) {
start {
await Promise.anyof($promise, Promise.in($time));
$promise ?? await($promise) !! die(TimedOut.new)
}
}
这将再次与任何 $promise
一起工作,传递结果或异常,否则抛出超时异常。
所有这些要记住的是,它们实际上不会影响任何正在进行的工作的取消。这可能无关紧要,也可能很重要。如果是后者,您可能需要:
- A
Promise
用于传达已取消;你在取消时保留它,并在执行取消的代码中轮询它
- 查看使用
Supply
范例,其中有一个取消模型(关闭水龙头)。
我知道我可以安排 Promise
在给定的时间内保存
my $promise = Promise.in($seconds);
但是我怎样才能安排它坏掉呢?具体来说,我正在考虑一个 "timeout" 的承诺,这样它就可以保留一定的时间,否则就会失败。
我可以用另一个 Promise
来做这个,就像这样:
my $promise = Promise.new;
...
Promise.in($seconds).then: { $promise.break };
但这感觉有点……浪费。有更好的方法吗?
一个常见的模式是这样写:
await Promise.anyof($the-promise, Promise.in(10));
if $the-promise {
# it finished ahead of the timeout
}
else {
# it timed out
}
这并没有表现为损坏的 Promise
,尽管这并非全是坏事(因为无论如何在许多情况下您都需要区分取消与错误,因此您仍然需要进行一些匹配关于异常类型)。此因式分解还有一个优点,即 $the-promise
不必是您有权访问 keep/break.
也可以这样总结:
class TimedOut is Exception {}
sub timeout($promise, $time) {
start {
await Promise.anyof($promise, Promise.in($time));
$promise ?? await($promise) !! die(TimedOut.new)
}
}
这将再次与任何 $promise
一起工作,传递结果或异常,否则抛出超时异常。
所有这些要记住的是,它们实际上不会影响任何正在进行的工作的取消。这可能无关紧要,也可能很重要。如果是后者,您可能需要:
- A
Promise
用于传达已取消;你在取消时保留它,并在执行取消的代码中轮询它 - 查看使用
Supply
范例,其中有一个取消模型(关闭水龙头)。