【发布时间】:2020-04-04 19:49:20
【问题描述】:
在 Flutter 中我们使用 async await 和 Future,有人可以解释一下,如果我们不使用另一个线程(我们不能在 dart 中)并且只在主 UIThread 上运行作业,应用程序不会变得不稳定,因为即使如果我们正在等待作业执行,它最终只会在 UIThread 上执行。 我也在某处读到过有关隔离的信息。但无法描绘出确切的画面。如果有人能详细解释一下。
【问题讨论】:
在 Flutter 中我们使用 async await 和 Future,有人可以解释一下,如果我们不使用另一个线程(我们不能在 dart 中)并且只在主 UIThread 上运行作业,应用程序不会变得不稳定,因为即使如果我们正在等待作业执行,它最终只会在 UIThread 上执行。 我也在某处读到过有关隔离的信息。但无法描绘出确切的画面。如果有人能详细解释一下。
【问题讨论】:
当谈到 Dart 中的异步方法时,我认为你错过了一些东西。
Dart 是单线程编程语言,Java 或 C# 是多线程编程语言,忘记async 作为新线程,在 Dart 中不会发生。
Dart 是一种单线程编程语言。这意味着 Dart 一次只能运行一条指令,而 Java 可以同时运行多条指令。
通常,您在 Dart 中所做的一切都将从 UI-Thread 开始。无论你在 Dart 中调用什么方法,无论是使用sync、async、then,它们都将在 UI-Thread 上运行,因为 Dart 是单线程。
在 Javascript 和 Dart 等单线程语言中,异步方法不是并行执行的,而是遵循由事件循环处理的常规事件序列。如果您在多线程语言中运行以下代码,其中 fetch 需要一些时间来执行,则会出现一些问题(我会给出一些方法,如下所示):
String user = new Database.fetch(David);
String personalData = new Database.fetch(user);
您将在 user 中收到 David 的数据,之后,您将收到您的数据。 这将锁定您的 UI,不像 Java 等具有线程的语言,您可以在后台执行此任务,在另一个线程上,并且 UI-Thread 将顺利运行。
如果你在 Dart 这样做
String user = new Database.fetch(David);
String personalData = new Database.fetch(user);
user 在personalData 中将为null,因为fetch 事件是一个Future。
如何在 Dart 中解决这个问题?
String user = await Database.fetch(David);
String personalData = await Database.fetch(user);
对于那些喜欢更实用的范例(我不喜欢它)的人,您可以使用then。
Database.fetch(David).then((user){
Database.fetch(user).then((personal){
String personalData = personal;
});
});
但是,假设您在该数据库中有数十亿数据,这项繁重的任务可能会导致屏幕上的动画冻结,并且您会在用户的 UI 中看到卡顿,为此发明了隔离。
Dart Isolates 为您提供了一种在 Dart 中执行真正多线程的方法。它们有自己独立的堆(内存),并在后台运行代码,就像多线程语言的线程一样。我可以解释隔离是如何工作的,但它会使这个响应很长,目标只是区分异步和多线程方法。
使用隔离解决上述问题的一种简单方法是使用compute。
Compute 是为了方便创建隔离区而创建的,您只需传递该函数将执行的函数和数据,就是这样!
重要的是要记住,compute 是 Future,因此您必须使用 await 或 then 来获得其结果。
在我们的示例中,我们可以创建一个新线程并在完成后通过像这样调用计算来获取其结果:
String user = await compute(Database.fetch,David);
String personalData = await compute(Database.fetch,user);
很简单,不是吗?
总结:
在 Dart 中等待一段时间才能完成的所有事情都被称为“未来”。
要等待将未来的结果分配给变量,请使用await 或then。
异步方法(await 和 then)可用于从 Future 获取结果,并在主线程上执行,因为 Dart 是单线程的。
如果你想在一个新线程上运行任何函数,你可以创建一个隔离。 Dart 提供了一个易于使用的隔离包装器compute,您只需传递一个将要处理的方法和将要处理的数据,它会在将来返回其结果。
英语不是我的第一语言,因此我不想写这么多,但我希望我能帮助区分多线程异步编程和单线程异步编程。
【讨论】: