我向具有未来“requestServer”的服务器发起请求。 我想在系统中轮询特定值(在请求完成时从false传递到true)并在完成时返回。
代码可能就是这样,但“while”同步和“checkOperation”是异步的吗?
return requestServer().then((operation) {
var done = false;
while (done)
return checkOperation(operation).then((result) {
done = (result == true);
});
sleep(10);
}
});
有什么想法吗?
答案 0 :(得分:1)
我想这不是你想要的,但据我所知,没有办法阻止执行,所以你必须使用回调。
void main(List<String> args) {
// polling
new Timer.periodic(new Duration(microseconds: 100), (t) {
if(isDone) {
t.cancel();
someCallback();
}
});
// set isDone to true sometimes in the future
new Future.delayed(new Duration(seconds: 10), () => isDone = true);
}
bool isDone = false;
void someCallback() {
print('isDone: $isDone');
// continue processing
}
您当然可以将回调作为参数传递而不是硬编码,因为函数是Dart中的第一类成员。
答案 1 :(得分:1)
答案 2 :(得分:1)
当您想要返回Futures的构建函数时,使用Completers有时很有用。认为requestServer()也生活在Future中,所以你将把结果威胁为Future。
return requestServer().then((operation) {
// This is necessary then you want to control async
// funcions.
Completer completer = new Completer();
//
new Timer.periodic(const Duration(seconds: 10), (_) {
checkOperation(operation).then((result) {
// Only when the result is true, you pass the signal
// that the operation has finished.
// You can alse use `completer.complete(result)` if you want
// to pass data inside of the future.
if (result == true) completer.complete();
});
});
// You return the future straight away.
// It will be returned by requestServer();
return completer.future;
});
答案 3 :(得分:0)
我在 TestUtil
库中使用了这样的函数:
static Future<bool> waitUntilTrue(bool Function() callback,
{Duration timeout: const Duration(seconds: 2),
Duration pollInterval: const Duration(milliseconds: 50)}) {
var completer = new Completer<bool>();
var started = DateTime.now();
poll() {
var now = DateTime.now();
if (now.difference(started) >= timeout) {
completer.completeError(Exception('timed out in waitUntilTrue'));
return;
}
if (callback()) {
completer.complete(true);
} else {
new Timer(Duration(milliseconds: 100), () {
poll();
});
}
}
poll();
return completer.future;
}
然后在我的测试代码中,我将执行以下操作:
await TestUtil.waitUntilTrue(() => someObj.isDone);
编辑:
请注意,如果您在 testWidgets
测试中使用它,则必须做一些额外的工作,因为它依赖于实际发生的异步工作:
await tester.runAsync<bool>(
() => TestUtil.waitUntilTrue(() => myObj.isLoaded),
additionalTime: Duration(seconds: 5));