为什么 Flutter 中的网络请求不会阻塞 UI

Luc*_*Dog 6 dart flutter

我知道 Dart 是单线程的,flutter 也是,所以如果我做一些繁重的任务,它会阻塞 UI 事件队列,但是网络请求需要几秒钟而不阻塞 UI。

那么,为什么 Socket 不会阻塞 UI?困扰我的是为什么socket不会阻塞UI,但是繁重的任务会,虽然它们都是异步任务。

例如,此代码将阻止 UI

@override
void initState() {
super.initState();
Future((){
  var result;
  for (var i = 0; i < 1000000; ++i) {
    result = 'result is $i';
  }
  print(result);
});
Run Code Online (Sandbox Code Playgroud)

此代码是正常的 HTTP 请求?它不会阻塞 UI

get() async {
  var httpClient = new HttpClient();
  var uri = new Uri.http(
      'example.com', '/path1/path2', {'param1': '42', 'param2': 'foo'});
  var request = await httpClient.getUrl(uri);
  var response = await request.close();
  var responseBody = await response.transform(UTF8.decoder).join();
}
Run Code Online (Sandbox Code Playgroud)

socket之所以不阻塞UI,是为了将请求过程拆分成多个部分?并将这些部分发送到当前的微任务队列?正如这个答案所说:

/sf/answers/3974859941/

那么,有谁知道套接字是如何异步实现的?socket是使用Isolate、Future还是其他方式?socket运行在UI线程,还是其他线程?

并且,如果我必须执行无法在 UI 线程中拆分的繁重任务(例如文本布局),我该怎么办?


补充说明?

我知道如何使用 Future 和 Isolate,但是我遇到了一个问题。

如果在隔离中使用 TextPainter.layout 会得到编译器错误未找到本机函数。

我需要布局很多单词并且需要很长时间(100ms+),它会阻塞 UI 线程。

我该怎么办?

https://github.com/flutter/flutter/issues/30604

UI 包的 Flutter 引擎原生 API 仅在主隔离中可用。

https://github.com/flutter/flutter/issues/30604#issuecomment-481380706

现在,您必须编写自己的换行逻辑 - 也许作为插件。我们目前没有任何 API 用于在单独的隔离中进行文本布局。@GaryQian 可能对此也有其他想法。

https://github.com/flutter/flutter/issues/30604#issuecomment-526013977

所以我必须在UI线程中做文本布局(使用TextPainter),虽然写一个插件可以解决这个问题并且效果很好,有没有更简单的方法?

我想我可以从socket的实现细节中得到帮助,所以我提出了这个问题。

Kir*_*iya 5

在 dart 中,网络调用是asnycronous自然的并返回Future。如果有任何内容asynchronous,它会在后台运行并在任务完成时返回结果或响应。它与Promisejavascript 中的非常相似。以下是从官方文档中获取的与 dart 中的 Async 相关的关键术语列表。

关键术语:


同步操作:同步操作阻止其他操作执行,直到它完成。
同步函数:同步函数只执行同步操作。
异步操作:一旦启动,异步操作允许其他操作在完成之前执行。
异步函数:一个异步函数至少执行一个异步操作,也可以执行同步操作。

在您的情况下,您已经使用Future但函数必须通过await屈服以允许其他操作在隔离中执行。如果你不让步,它会阻塞 UI 线程。这正是你在第一个代码块中得到的,UI 被阻止了。您已经使用过,Future但计算仍然在其中进行同步。有一个精确的帖子here以供更多参考。

  • 为什么套接字不阻塞 UI?这就是我困惑的地方。 (2认同)
  • 但是在Android上(4.0之前),Socket会阻塞UI。所以我猜Socket不是隔离的,但Flutter系统隔离了socket。 (2认同)