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

标签 flutter dart

我知道 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);
});

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

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

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

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

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

补充说明:

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

if use TextPainter.layout in isolate will get a compiler error native function not found.

I need layout many words and it takes a long time (100ms+), it will block UI thread.

What should I do?



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

The Flutter engine native APIs for the UI package is only available in the primary isolate.



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

right now you would have to write your own line-breaking logic - perhaps as a plugin. We don't currently have any API for doing text layout in a separate isolate. @GaryQian might have some other idea about this too.



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

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

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

最佳答案

在 dart 中,网络调用是 asnycronous自然与返回Future .什么时候是asynchronous ,它在后台运行并在任务完成时返回结果或响应。它与 Promise 非常相似在 JavaScript 中。以下是 dart 中与异步相关的关键术语列表,取自 Official Docs .

关键术语:

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

在您的情况下,您使用了 Future但函数必须通过 await允许其他操作在隔离中执行。如果你不让步,它会阻塞 UI 线程。这正是你在第一个代码块中得到的,并且 UI 被阻塞了。您使用过Future但计算仍然是同步的。有一个精确的Post这里有更多引用。

关于flutter - 为什么 Flutter 中的网络请求不会阻塞 UI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58161310/

相关文章:

design-patterns - 扩建工厂

flutter - Future<void> vs void

dart - Flutter-来自WebViewScaffold中显示的网页的电话调用

flutter - 与SharedPreferences一起使用时,FutureBuilder不起作用

android - Flutter:尝试将数据添加到 map 列表时出错

flutter - 尝试在 flutter 中进行改造并在制作 restclient 时出错

dart - 如何实现 ControlValueAccessor 将属性从 num 转换为 String,反之亦然

Flutter:选择当前选项卡时如何检测选项卡 onclick?

flutter 在2个标记之间绘制路线

Dart/SQFlite 导入错误