超时的用户输入无法正常工作

sid*_*com 6 asynchronous user-input promise raku

为什么循环周期在超时后不像以前那样工作(不再打印用户输入)?

#!/usr/bin/env raku

loop {
    my $str;
    my $timeout = Promise.in( 5 ).then({
        $str = 'Timeout';
    });
    my $user = Promise.start({
        $str = prompt '>';
    });
    await Promise.anyof( $timeout, $user );
    if $str eq 'q' {
        last;
    }
    say "[$str]";
}
Run Code Online (Sandbox Code Playgroud)

dar*_*rch 6

这是因为您正在与错误的 通话 通话prompt,这是在已关闭不同变量的承诺中$str。第二次及以后调用prompt阻塞,等待第一个调用完成。但是$str接收第一个调用的值超出了范围,所以什么也没有发生。

这听起来很奇怪,但是在我更全面地剖析它的同时,您可以运行一个实验来帮助您的直觉:运行脚本,等待超时,然后q快速连续输入两次。脚本在第二个之后退出。为什么?

在第一个循环中,我们声明了一个变量$str,我将把它称为“$str数字 1”,并创建一个Promise关闭$str数字 1 并调用prompt. prompt附加到STDIN并且直到看到换行符才返回。当超时到期时,该调用prompt不会中断。它仍在运行。还在等。$user即使变量$user即将超出范围,它所附加的承诺(我们称之为承诺 1)仍然处于活动状态。

在第二个循环中,我们声明了一个新变量$str(“ $strnumber 2”),创建了一个Promise关闭它的变量,然后prompt再次调用。但是另一个对 的调用prompt仍在使用STDIN,因此新调用会阻塞并等待STDIN变为可用。如果你现在输入一些东西,它会被最初的调用看到prompt,它被附加到$user承诺 1 并在$str数字 1 上关闭。

$strprompt返回时会更新数字 1 ,但这无关紧要,因为您已停止查看它。该if $str eq 'q'条件是要检查$str2号,因为这是在电流回路声明的变量。

第二次调用promptthen 立即要求输入,如果您q在超时到期之前输入,它会更新$str它关闭的版本,$str编号 2。由于这是您的条件正在检查的版本,因此循环终止。

每次超时都会开始一个新的prompt而不终止旧的,这意味着用户输入的输入永远不会附加到$str您正在检查的相同内容上。即使您检查原始变量,后续调用prompt仍然会发生,并且即使在执行离开块后也会继续提示。

由于prompt没有办法指定超时并且 Raku 没有办法“杀死” schedule Promises,我认为你不能用prompt.