我在执行 Flutter/Dart 异步代码时遇到问题,就像它是如何工作的一样

Yas*_*rma 2 dart flutter

在 Flutter 中,我们使用 async await 和 Future,有人可以解释一下,如果我们不使用另一个线程(我们不能在 dart 中使用)并且仅在主 UIThread 上运行作业,应用程序也不会变得不稳定,因为即使我们是等待作业执行它最终只会在 UIThread 上执行。我也在某处读到过隔离。但无法描绘出准确的画面。如果有人能详细解释一下。

jon*_*ges 6

我认为您错过了 Dart 异步方法中的某些内容。Dart 是单线程编程语言,Java 或 C# 是多线程编程语言,忘记 async 作为新线程,它在 Dart 中不会发生。Dart 是一种单线程编程语言。这意味着 Dart 一次只能运行一条指令,而 Java 可以同时运行多条指令。

通常,您在 Dart 中所做的一切都将从 UI-Thread 开始。无论你在 Dart 中调用什么方法,无论是使用同步、异步,然后,它们都将在 UI-Thread 上运行,因为 Dart 是一个单线程。在单线程语言中,比如 Javascript 和 Dart,异步方法不是并行执行的,而是遵循由事件循环处理的常规事件序列。如果您在多线程语言中运行以下代码,其中 fetch 需要一些时间来执行,则存在一些问题(我会说方法,我们将在下面看到):

String user = new Database.fetch(David);
String personalData = new Database.fetch(user);
Run Code Online (Sandbox Code Playgroud)

您将在 user 中收到 David 的数据,之后,您将收到您的数据。这将锁定您的 UI,并且对于那些语言,例如 Java 有线程,您可以使用它在后台在另一个线程上执行此任务,并且 UI-Thread 将顺利运行。

如果你在 Dart 上这样做

String user = new Database.fetch(David);
String personalData = new Database.fetch(user);
Run Code Online (Sandbox Code Playgroud)

user 在personalData 中将为null,因为fetch 事件是一个Future。

如何在 Dart 中解决这个问题?

String user = await Database.fetch(David);
String personalData = await Database.fetch(user);
Run Code Online (Sandbox Code Playgroud)

对于那些喜欢更多功能范式(我不喜欢它)的人,您可以使用。

Database.fetch(David).then((user){
Database.fetch(user).then((personal){
String personalData = personal;
});
});
Run Code Online (Sandbox Code Playgroud)

但是,假设您在该数据库中有数十亿条数据,这项繁重的任务可能会导致屏幕上的动画冻结,并且您会看到用户 UI 出现卡顿,因为隔离是发明的。

Dart Isolates 提供了一种在 Dart 中执行真正多线程的方法,它们有自己独立的堆(内存),并在后台运行代码,就像多线程语言的线程一样。我可以解释隔离是如何工作的,但它会使这个响应变得非常大,目标只是区分异步/多线程方法。

解决上述问题的方法很简单,即使用隔离,即使用计算。

创建 Compute 是为了方便创建隔离,您只需传递函数和该函数将执行的数据,就这样!重要的是要记住,compute 是一个 Future,所以你必须使用 await 或 then 来获得它的结果。

在我们的示例中,我们可以创建一个新线程并在我们完成调用计算时获得它的结果,如下所示:

String user = await compute(Database.fetch,David);
String personalData = await compute(Database.fetch,user);
Run Code Online (Sandbox Code Playgroud)

很简单,不是吗?

简历:一切等待一段时间才能完成的东西,在飞镖中被称为“未来”。要等待未来的结果填充变量,请使用 await 或 then。用于从 Future 获取结果的异步方法(await 和 then)在主线程上执行,因为 Dart 是单线程的。如果要在新线程上运行任何函数,可以创建一个隔离。Dart 提供了一个易于使用的称为计算的隔离包装器,您只需在其中传递一个将被处理的方法,以及将被处理的数据,它会在未来将所有结果返回给您。

  • 注意:如果您要使用计算,请确保您使用的是静态或顶级方法(请参阅示例中我使用 Database.fetch 这并非偶然,如果您需要调用 Database().fetch 或需要创建它的一个实例,意味着它不是一个静态方法并且不能与隔离一起工作)。

英语不是我的第一语言,因此我不想写这么多,但我希望我能帮助区分多线程异步编程和单线程异步编程。

  • 分离株的产卵需要一些时间才能开始。通常为 1 至 3 秒。我建议仅在非常繁重的任务或直接影响 UI 流畅性的任务中使用隔离。让你的应用程序没有隔离,如果你检查给定任务的卡顿,我只需用计算(函数,任何东西)替换函数(任何东西)。在多线程语言中,线程越多越好,在单线程中,仅在必要时才使用它们。 (3认同)