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

问题描述

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 中并将其放入事件循环中。但是,我们正在等待的 Future (await sendRequest(fullName)) 如何不阻止运行另一个同步代码?我们应该等待请求完成,但它也需要一些代码来检查我们是否收到或未收到响应。它如何不阻止其他操作,例如按钮点击?

解决方法

函数在第一个 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 语句。因此,即使是这样一个简单的例子,也可能会被转换成比绝对必要的更复杂的东西)。