【问题标题】:Future and async behavior is not the same and I don't get it未来和异步行为不一样,我不明白
【发布时间】:2019-08-26 06:31:58
【问题描述】:

我在 Dart 中遇到了 async 方法和 Future 的问题。

我想我做错了/理解错了,但我不知道是什么。

我试图找出Futureasync 之间的区别并了解事件循环的工作原理。我阅读了文档和很多关于此的文章。我以为我理解了,所以我尝试编写一些代码来创建一个带有 sleep() 调用的 Future 对象。

首先,我尝试使用Future,我认为它的行为应该是这样的:

main(List<String> arguments) {
    print('before future');
    test_future();
    print('after future');
}

test_future() {
    Future (() {
        print('Future active before 5 seconds call');
        sleep(Duration(seconds: 5));
        print('Future active after 5 seconds call');
    }).then((_) => print("Future completed"));
}

所以返回:

  1. 在未来之前打印
  2. 创建一个future对象,放入事件队列并立即返回
  3. 在未来之后打印
  4. 从事件队列中调用未来的代码
  5. 5 秒前打印
  6. 等待 5 秒
  7. 5 秒后打印*
  8. 打印未来完成

我觉得这一切都很正常。

现在,我正在尝试对async 做同样的事情。从文档中,将async 关键字添加到函数中,使其立即返回Future

所以我写了这个:

main(List<String> arguments) {
   print('before future 2');
   test().then((_) => print("Future completed 2"));
   print('after future 2');
}

test() async {
    print('Future active before 5 seconds call');
    sleep(Duration(seconds: 5));
    print('Future active after 5 seconds call');
}

正常情况下,调用test().then()时,应该将test()的内容放入事件队列,并立即返回一个Future,但不会。行为是这样的:

  1. 在未来 2 之前打印
  2. 调用 test() 函数(我认为应该返回一个未来,但代码现在执行)
  3. 5 秒前打印
  4. 等待 5 秒
  5. 5 秒后打印
  6. 打印未来已完成 2
  7. 在未来 2 之后打印

如果我没有正确使用async 或者有什么问题,有人可以解释一下吗?

最好的

【问题讨论】:

  • 我没有深入研究你的代码,但你应该知道sleep() 只是阻塞了整个程序。 sleep() 与事件循环或异步执行没有任何关系。也许您想改用await Future.delayed(const Duration(seconds: 5), (){});
  • 是的,我在一小时前就发现了自己。 sleep 不是由系统或服务器执行的,它是在 dart 单线程内执行的,这就是它阻塞代码的原因。我想模拟一个漫长的过程来使用异步/等待,但这不是最好的方法。顺便说一句,如果我必须执行不使用系统 I/O 或用户输入的繁重操作,行为是否与 sleep 相同?在这种情况下是否必须使用隔离?就像我将 sleep 替换为一个将 int 增加 10 亿次的循环
  • async 系统调用不会阻塞隔离。事件队列仍在处理中(在调用系统调用后立即继续)。如果您进行同步系统调用,它们会像 sleep 一样阻塞。
  • 不,您不能调用系统调用同步或异步。在dart:io 的系统调用(如api.dartlang.org/stable/2.2.0/dart-io/File/readAsLinesSync.html)中经常有同步和异步变体。即使sleep 没有sync 后缀,它也是同步的,无法解决。你可以Future.delayed()如上图以异步方式获得效果。
  • 谢谢大家。如果你想让我打勾,你可以写一个答案。

标签: asynchronous dart async-await future


【解决方案1】:

你应该知道 sleep() 只是阻塞了整个程序。 sleep() 与事件循环或异步执行没有任何关系。也许您想改用:

await Future.delayed(const Duration(seconds: 5), (){}); 

async 系统调用不会阻塞隔离。事件队列仍在处理中(在调用系统调用后立即继续)。如果您进行同步系统调用,它们会像睡眠一样阻塞。

在 api.dartlang.org/stable/2.2.0/dart-io/File/readAsLinesSync.html 等系统调用的dart:io 中经常存在同步和异步变体。尽管sleep 没有同步后缀,但它是同步的,无法解决。您可以使用如上所示的Future.delayed() 以异步方式获得效果。

【讨论】:

    猜你喜欢
    • 2023-03-10
    • 1970-01-01
    • 2019-11-14
    • 2017-09-05
    • 1970-01-01
    • 2021-12-28
    • 2020-03-28
    • 2016-03-31
    • 1970-01-01
    相关资源
    最近更新 更多