asynchronous - 超时的用户输入无法按预期工作
问题描述
为什么在超时(不再打印用户输入)后循环周期不能像以前一样工作?
#!/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]";
}
解决方案
这是因为您正在与错误的通话通话prompt
,这是在一个已关闭不同变量的承诺中$str
。第二个和以后的调用prompt
阻塞,等待第一个调用完成。但是$str
接收第一个调用的值超出了范围,所以什么也没有发生。
这听起来很奇怪,但是当我更全面地剖析它时,你可以运行一个实验来帮助你的直觉:运行脚本,等待超时,然后q
快速连续输入两次。脚本在第二个之后退出。为什么?
在第一个循环中,我们声明一个变量$str
,我将其称为“$str
数字 1”,并创建一个Promise
关闭$str
数字 1 并调用prompt
. prompt
附加到STDIN
并且在看到换行符之前不会返回。当超时到期时,该调用prompt
不会中断。它仍在运行。还在等待。$user
即使变量$user
即将超出范围,它所附加的承诺(我们称之为承诺 1)仍然有效。
在第二个循环中,我们声明一个新变量$str
(“$str
数字 2”),创建一个Promise
关闭它的变量,然后再次调用prompt
。但另一个调用prompt
仍在使用STDIN
,因此新调用阻塞并等待STDIN
变为可用。如果你现在输入一些东西,它会被原来的调用看到prompt
,它附加到$user
承诺 1 并关闭了$str
数字 1。
$str
返回时会更新数字 1 prompt
,但这并不重要,因为您不再查看它。if $str eq 'q'
条件将检查数字$str
2,因为这是在当前循环中声明的变量。
对 then 的第二次调用prompt
立即要求输入,如果您q
在超时到期之前输入,它会更新$str
它关闭的版本,$str
编号 2。由于这是您的条件正在检查的版本,因此循环终止。
每次超时都会开始一个新的超时prompt
而不终止旧的超时,这意味着用户键入的输入永远不会附加到$str
您正在检查的相同。即使您检查原始变量,后续调用prompt
仍然会发生,并且即使在执行离开块后也会继续提示。
由于prompt
没有办法指定超时并且 Raku 没有办法“杀死”预定Promises
,我不认为你可以用prompt
.
推荐阅读
- android - Android Studio 和 Jax-rs 中的登录和 Oauth
- c++ - 如何使用linux接受多个输入进行操作
- twitter-bootstrap - 为 Bootstrap 4 重新排序移动设备中的列
- c++ - Apache Ignite C++ 瘦客户端:如何放置/获取字节数组?
- sql - 对低基数字段进行索引
- java - 在 Java 中执行 .class 文件
- ffmpeg - 只读取“-vf scale.....”,忽略剩余的 -vf 选项:使用“,”来分隔过滤器,即使没有其他 vf 存在
- android - 为什么 Delphi 10.3.2 找不到 Android 应用程序的 Posix.Locale.pas 单元?
- node.js - Nodejs - 使用不同的包版本构建
- mysql - 一个 LEFT JOIN 的 4 表查询