likes
comments
collection
share

[译] Dart异步之Isolates 和event loops

作者站长头像
站长
· 阅读数 63

Dart是一个单线程的语言,它提供了futurestreambackground wotk、和其他的事件、异步,对于Flutter而言,本章节讲解了Dart的后台工作基础:隔离和事件循环。

Isolates

所有Dart代码都在其中运行隔离程序。它就像是机器上的一个小空间,具有自己的私有内存块和一个运行事件循环的单个线程。

[译] Dart异步之Isolates 和event loops

在许多其他语言(例如C ++)中,您可以让多个线程共享相同的内存并运行所需的任何代码。但是,在Dart中,每个线程都处于其自己的隔离区中,并拥有自己的内存,并且该线程仅处理事件(一分钟内会处理更多事件)。

许多Dart应用程序都在单个隔离中运行所有代码,但是如果需要,您可以拥有多个。如果要执行的计算量如此之大,以至于如果它在主隔离中运行,可能会导致丢帧,那么可以使用Isolate.spawn()Fluttercompute()函数。这两个函数都创建了一个单独的隔离程序来处理数字,使您的主要隔离程序可以自由地(例如)重建和渲染小部件树。

[译] Dart异步之Isolates 和event loops

新隔离区拥有自己的事件循环和内存,即使原始隔离区是该新隔离区的父级,也不允许其访问。这就是孤立的名称:这些小空间彼此隔离。

实际上,隔离器可以一起工作的唯一方法是通过来回传递消息。一个隔离向另一个发送消息,接收隔离使用其事件循环处理该消息。

[译] Dart异步之Isolates 和event loops

缺少共享内存听起来可能很严格,尤其是如果您使用的是JavaC ++之类的语言时,但这对Dart编码人员来说有一些关键的好处。

例如,隔离中的内存分配和垃圾回收不需要锁定。只有一个线程,因此,如果不很忙,您就知道内存没有被更改。这对于Flutter应用程序来说效果很好,有时需要快速构建和拆除一堆小部件。

Event loops

现在,您已经对隔离有了基本的介绍,让我们深入研究真正使异步代码成为可能的事情:事件循环。 想象一下,应用程序的生命周期在时间轴上延伸。该应用程序启动,该应用程序停止,并且在一系列事件之间发生–来自磁盘的I/O,来自用户的手指敲击……各种各样的东西。 您的应用无法预测这些事件何时发生或以什么顺序发生,因此必须使用一个永不阻塞的线程来处理所有这些事件。因此,该应用运行一个事件循环。它从事件队列中获取最旧的事件,进行处理,返回到下一个事件,然后进行处理,依此类推,直到事件队列为空。 应用程序在整个运行过程中-您在屏幕上点击,下载内容,计时器关闭-该事件循环不断循环,一次处理一次这些事件。

[译] Dart异步之Isolates 和event loops

当操作中断时,线程只会挂出,等待下一个事件。它可以触发垃圾收集器,获取咖啡,等等。 Dart用于异步编程的所有高级API和语言功能(期货,流,异步和等待)都基于此简单循环而构建。 例如,假设您有一个启动网络请求的按钮,如下所示:

RaisedButton(
  child: Text('Click me'),
  onPressed: () {
    final myFuture = http.get('https://example.com');
    myFuture.then((response) {
      if (response.statusCode == 200) {
        print('Success!');
      }
    });
  },
)

当你启动你的APPFlutter编译这个button,然后渲染它,然后APP就开始等待事件。

您应用的事件循环只是闲着,等待下一个事件。与按钮无关的事件可能会进入并得到处理,而按钮坐在那里等待用户点击它。最终他们做到了,而点击事件进入了队列。

该事件将被处理。 Flutter看着它,并且渲染系统说:“那些坐标与凸起的按钮匹配,”因此Flutter执行onPressed函数。该代码启动一个网络请求(返回一个将来的请求),并使用then()方法注册一个将来的完成处理程序。 而已。循环完成了该点击事件的处理,并且已将其丢弃。 现在,onPressedRaisedButton的一个属性,并且网络事件将回调用于将来,但是这两种技术都在做相同的基本操作。它们都是告诉Flutter的一种方式,“嘿,稍后,您可能会看到一种特定类型的事件。当您这样做时,请执行这段代码。” 因此,onPressed正在等待点击,而未来正在等待网络数据,但是从Dart的角度来看,这些都只是队列中的事件。 这就是Dart中异步编码的工作方式。期货,数据流,异步和等待-这些API只是告诉您的方式 Dart的事件循环,“这里有一些代码,请稍后运行。” 如果我们回顾一下该代码示例,您现在可以确切地看到它如何分解为特定事件的块。 有初始版本(1),点击事件(2)和网络响应事件(3)。

RaisedButton( // (1)
  child: Text('Click me'),
  onPressed: () { // (2)
    final myFuture = http.get('https://example.com');
    myFuture.then((response) { // (3)
      if (response.statusCode == 200) {
        print('Success!');
      }
    });
  },
)

习惯了使用异步代码后,您将开始在各处识别这些模式。在继续使用更高级别的API时,了解事件循环将有所帮助.

我们快速了解了Dart中的隔离,事件循环和异步编码的基础。如果您要查找更多详细信息,例如微任务队列的工作方式,请参阅过时的,但仍备受喜爱的文章事件循环和Dart

原文:medium.com/dartlang/da…

翻译 fgyong

日期 2020.7.28

转载自:https://juejin.cn/post/6854573221753618439
评论
请登录