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

问题描述 投票:0回答:2

我知道Dart是单线程的,也很颤振,所以如果我执行一些繁重的任务,它将阻止UI事件队列,但是网络请求会花费几秒钟而不会阻止UI。

所以,为什么Socket不阻止UI?使我困扰的是为什么套接字不阻止UI,但是繁重的任务却阻止了UI,尽管它们都是异步任务。

例如,此代码将阻止UI

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

此代码是正常的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();
}

套接字不阻止UI的原因是将请求过程分为多个部分?并将这些部分发送到当前的微任务队列,如以下答案所示:

https://stackoverflow.com/a/56783713/6540631

所以,有人知道套接字是如何异步实现的吗?套接字是否使用隔离,未来或其他方式?套接字在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),尽管编写插件可以解决此问题,并且效果很好,有没有更简单的方法?

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

flutter dart
2个回答
1
投票

在Dart中,网络呼叫具有asnycronous性质,并返回Future。当任何内容为asynchronous时,它将在后台运行,并在任务完成时返回结果或响应。它与javascript中的Promise非常相似。这是从Official Docs中摘录的与dart异步相关的关键术语列表。

关键术语:


同步操作:异步操作阻止其他操作执行直到完成。同步功能:异步功能仅执行同步操作。异步操作:一旦启动,异步操作将允许其他操作在完成之前执行。异步功能:异步功能至少执行一个异步操作,并且还可以执行同步操作。
在您的情况下,您使用了Future,但函数必须通过await屈服以允许其他操作在隔离中执行。如果您不屈服,它将阻塞UI线程。正是您进入了第一个代码块,UI被阻止了。您已使用Future,但计算仍在其中进行同步。这里有一个精确的Post供更多参考。

-1
投票

dart中的[async]函数不会阻塞UI或不会阻塞UI。

Future((){
  var result;
  for (var i = 0; i < 1000000; ++i) {
    result = 'result is $i';
  }
  print(result);
});

这不是异步功能。它与说new Future((){...相同。因此,这是Future类的承包商,承包商不是async函数,如果很重则它们将阻止UI。

请尝试以下示例:

@override
void initState() {
    super.initState();
    test();
}

test() async {
   Future((){
     var result;
     for (var i = 0; i < 1000000; ++i) {
       result = 'result is $i';
     }
     print(result);
   });
}
© www.soinside.com 2019 - 2024. All rights reserved.