是否可以使用超时而不会延迟?

时间:2019-12-27 11:50:24

标签: dart

我只是想了解超时在期货中的工作原理,但是我无法打断更复杂的事情。看一下这个非常简单的代码,我认为如果该循环花费的时间超过1秒,它将发生异常,但是不会发生。有人可以解释一下这里发生了什么吗?

我正在尝试使用此工具:https://dartpad.dartlang.org/

body {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.App {
  font-family: sans-serif;
  text-align: center;
}

.cloud-animate-enter {
  overflow: hidden;
  position: fixed;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 9999 !important;
  background-color: tomato;
  content: "";
  animation: cloud-start 1s ease-in-out;
}

@keyframes cloud-start {
  0% {
    transform: translateX(-100%);
  }

  50% {
    transform: translateX(0%);
  }

  100% {
    transform: translateX(100%);
  }
}

3 个答案:

答案 0 :(得分:2)

首先Future.timeout不会中断任何计算。 它会创建一个 new Future,如果原始的未来未及时完成,则以原始的Future的值或超时的结果来完成。这更像是需要两个期货:原始期货和一个期货使用Future.delayed创建,然后创建第三个Future,它将以 first 的结果完成,另外两个完成。

没有信号可以返回到最终完成原始计算的计算。除非您使其停止,否则它不会停止。

例如,Future.timeout的用例是似乎无法及时得出结果的网络连接。您无法停止该请求,但是可以停止等待答案,timeout就是这样。

您的示例中发生的事情是:

  • 您可以使用Future构造函数创建一个Future f1 。这样会安排持续时间为零的 timer 来调用参数函数。
  • 然后您在 f1 上致电timeout。这将启动一个持续时间为一秒的计时器,并返回将来的 f2
  • 然后您以then作为参数在 f2 上调用print。这会将侦听器放在 f2 上,并返回将来的 f3
  • 然后您在 f3 上调用catchError,这会将错误侦听器放在 f3 上,并返回将来的 f4 忽略)。
  • 然后控件返回事件循环,下一个事件是零持续时间计时器。
  • 调用Future构造函数的参数。它计数到500000000,然后返回值 v 并用该值完成 f1
  • f1 的结果传播到 f2 ,后者也以 v 完成。
  • f2 的结果由print打印,而 f3 null 结束。
  • f4 的结果被catchError忽略,并且 f4 null 结束。
  • 然后控件返回到事件循环。下一个事件是由Future.timeout启动的1秒计时器。可能已经过去了超过一秒钟,但这是它运行的最早机会。
  • Future.timeout计时器回调看到 f2 已经完成,什么也不做。
  • 控制权返回事件循环,由于它为空,因此程序结束。

答案 1 :(得分:0)

我认为您需要以这种方式调用timeout(Duration timeLimit,onTimeout());

so timeout(new Duration(seconds:1),printFunction())

import 'dart:async';
_onTimeout() => print("Time Out occurs");
void main() {
  new Future(() {
    var sum = 0;
    for (var i = 0; i < 500000000; i++) {
      sum += i;
    }
    return sum;
  }).timeout(new Duration(seconds: 1),onTimeout: _onTimeout());
}

答案 2 :(得分:0)

您的代码不起作用,因为您的将来值正在同步处理,因此事件循环除了正在运行的for循环外无法处理其他任何事情。我建议通读这些文章,以更好地了解https://medium.com/hackernoon/are-futures-in-dart-threads-2cdc5bd8063a https://medium.com/dartlang/dart-asynchronous-programming-isolates-and-event-loops-bffc3e296a6a的Future和事件循环。 解决此问题的快速方法是使用dart隔离(与package:isolate库一起使用),例如:

import 'dart:async';
import 'package:isolate/isolate.dart';

Future<void> main() async {
  var isolate = await IsolateRunner.spawn();
  var value = await isolate.run(func, null, timeout: Duration(seconds: 1));
  print(value);
}

int func(_) {
  var sum = 0;
  for (var i = 0; i < 500000000; i++) {
    sum += i;
  }
  return sum;
}

如果func()完成的时间超过1秒,它将引发TimeoutException,您可以设置onTimeout函数,使其在超时时运行。