执行期货直到参数变为真

时间:2014-03-11 17:36:32

标签: dart dart-async

我向具有未来“requestServer”的服务器发起请求。 我想在系统中轮询特定值(在请求完成时从false传递到true)并在完成时返回。

代码可能就是这样,但“while”同步和“checkOperation”是异步的吗?

return requestServer().then((operation) {
  var done = false;
  while (done)
    return checkOperation(operation).then((result) {
      done = (result == true);
    });
    sleep(10);
  }
});

有什么想法吗?

4 个答案:

答案 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));