我试图在5秒后打破循环,所以我使用了dart的Timer类。但在每个循环状态中,timer.tick值都是1。我需要帮助,如何在5秒或任何特定持续时间后中断循环?
import 'dart:async';
import 'dart:io';
main(List<String> args) {
String usrName;
Timer.periodic(Duration(seconds: 1), (timer) {
while (true) {
print("What's you're name?");
usrName = stdin.readLineSync() as String;
print("Welcome $usrName.");
//print("${timer.tick}s passed");
if (timer.tick == 5) {
print("Ended");
timer.cancel();
break;
}
}
});
}发布于 2021-06-07 04:57:17
你目前的方法有很多地方不对劲。您已经创建了一个每秒都会创建一个新循环的Timer,但是您想要的是一个具有可以中断它的Timer的单个循环。而且,不幸的是,您将无法使用stdin.readLineSync(),因为它将阻塞执行,直到用户输入一个输入行。你需要一种完全不同的方法。
Future和Stream都有一个可以抛出TimeoutException (或返回/发出指定值)的.timeout方法。不幸的是,stdin不提供异步读取行的直接方法,因此您需要手动对其使用LineSplitter。
另一个复杂的问题是,stdin是一个单订阅读流,这使得读取单独的行有点笨拙。我们可以使用package:async的StreamQueue来让它更直观。
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:async/async.dart';
Future<void> main(List<String> args) async {
final lines = StreamQueue<String>(utf8.decoder
.bind(stdin)
.transform(const LineSplitter())
.timeout(const Duration(seconds: 5)));
var questions = [
'Question 1?',
'Question 2?',
'Question 3?',
];
var answers = <String>[];
for (var question in questions) {
print(question);
try {
answers.add(await lines.next);
} on TimeoutException {
break;
}
print('');
}
lines.cancel();
print('Got answers: $answers');
}发布于 2021-06-07 16:25:03
Dart中的同步循环不允许运行任何其他事件,包括会增加节拍的计时器事件。
或者使您的循环异步(通过在其中至少一个位置执行await,如果您希望计时器运行,请使用Future.delayed(Duartion.zero)来确保它允许计时器事件运行,而不仅仅是微任务)。
或者,如果我真的希望循环是同步的,我会做的是使用一个Stopwatch
var sw = Stopwatch()..start();
while (sw.elapsedMilliseconds < 5000) {
// keep doing
}
// done.这将停止循环。它不会使输入请求超时,也不允许在等待输入时运行其他任何东西。出于这些原因,您可能希望使用@jamesdlin建议的内容。
https://stackoverflow.com/questions/67859476
复制相似问题