【问题标题】:How does Dart run asynchronous code without blocking?Dart 如何在不阻塞的情况下运行异步代码?
【发布时间】:2021-06-10 20:41:25
【问题描述】:

Dart 如何在不阻塞的情况下运行异步代码? 例如:

void test(User user) async {
    print('test');

    String fullName = user.firstName + ' ' + user.lastName;

    final result = await sendRequest(fullName);

    print('${result}');
}

我了解 Dart 运行 async 函数时,它会在 await 之前执行代码,然后将剩余的代码包装到 Future 并放入 Event Loop 中。但是,我们正在等待的 Future (await sendRequest(fullName)) 如何不阻止运行其他同步代码?我们应该等待请求完成,但它还需要一些代码来检查我们是否收到了响应。怎么不阻塞其他操作,比如按钮点击?

【问题讨论】:

标签: dart asynchronous async-await event-loop


【解决方案1】:

函数在第一个await 处返回。它返回一个稍后将完成的未来(由于void 返回类型而被忽略)。函数中的所有其他内容都是响应来自其他期货(或流,如果您使用 await for)的回调而发生的。

这里的async函数基本上改写成这样的:

void test(User user) {
  print('test');
  String fullName = user.firstName + ' ' + user.lastName;
  return sendRequest(fullName).then((final result) { // <-- Returns here, synchronously.
    print('${result}');    // <-- Gets called by the future of `sendRequst(fullName)`.
  });
}

这种转换类似于continuation-passing style 转换,它采用延续(await 之后的函数体中的控制流)并将其变成一个函数。

(实际上,转换更复杂,因为它需要考虑循环,try/catch/finally,甚至break 语句。因此,即使是像这样的简单示例可能会被转换成比绝对必要的更复杂的东西)。

【讨论】:

  • @Irn 谢谢你的回答。我只是想澄清一下,我理解它是正确的。所以,在底层它是这样工作的:将我们正在等待的未来添加到事件循环中,然后将 await 转换为 .then() 并创建一个单独的函数来处理 await 关键字之后的内容。当我们等待的future(在这种情况下为await sendRequest())完成时,这个函数被添加到事件循环中,对吧?
  • 该函数被添加到您正在等待的未来中,以便在该未来完成时被调用。什么时候完全取决于未来背后的代码在做什么。当未来完成时,回调运行 - 可能在事件循环上,可能直接由未来。同样,完全取决于未来,好消息是您不需要关心这些,Future 类抽象了计算完成的方式和时间。
  • 感谢您的澄清
猜你喜欢
  • 1970-01-01
  • 2022-09-27
  • 2019-10-27
  • 2018-12-13
  • 2016-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
相关资源
最近更新 更多