如何在Raku中使承诺超时?


9

我知道我可以安排Promise在一定时间内保存

my $promise = Promise.in($seconds);

但是我该如何安排它被破坏?具体来说,我正在考虑一个将“超时”的承诺,这样它可以保留一定的时间,否则将失败。

我可以用另一个做Promise,就像这样:

my $promise = Promise.new;
...
Promise.in($seconds).then: { $promise.break };

但这感觉有点...浪费。有一个更好的方法吗?

Answers:


10

一个常见的模式是写这样的东西:

await Promise.anyof($the-promise, Promise.in(10));
if $the-promise {
    # it finished ahead of the timeout
}
else {
    # it timed out
}

但这并没有表现为Promise坏处,尽管这还不是很糟糕(因为无论如何在很多情况下您都需要区分取消与错误,因此您仍然必须对异常类型进行一些匹配)。此分解还具有$the-promise不必成为保留/中断权限的优点。

也可以将其包装成如下形式:

class TimedOut is Exception {}
sub timeout($promise, $time) {
    start {
        await Promise.anyof($promise, Promise.in($time));
        $promise ?? await($promise) !! die(TimedOut.new)
    }
}

它将再次与any一起使用$promise,传递结果或异常,否则抛出超时的异常。

所有这些要记住的是,它们实际上并不会影响正在进行的工作。这可能无关紧要,或者可能很重要。如果是后者,则可能需要:

  • Promise您用来传达已发生的取消的A ;您可以在取消时保留它,并在进行取消的代码中对其进行轮询
  • 要查看使用Supply范式的情况,那里有一个取消模型(关闭抽头)。

3
谢谢。这很有用。至少它可以保证承诺很便宜(!),并且可以像您建议的那样使用它们,也可以像我最初想到的那样使用它们。仍然感觉应该有一种(更多?)直截了当的方式说:“如果这个承诺没有在X秒钟内兑现,那就认为它已经破灭了”。我知道这并非在所有情况下都有意义,但我认为在某些情况下绝对有道理。
jja

3
它可能会在将来出现,但是可能只有当我们Promise在核心中也有某种取消条款时,因为它的语义会与这些条款有联系。
乔纳森·沃辛顿
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.