网站地图    收藏   

主页 > 前端 > dart入门教程 >

Dart异步编程:隔离和事件循环

来源:未知    时间:2023-05-09 09:17 作者:小飞侠 阅读:

[导读] Dart异步编程:隔离和事件循环 尽管Dart是一种单线程语言,但它提供了对futures、streams、background工作以及所有其他需要用现代、异步和(对于Flutter而言)反应式编程的内容的支持。本文...

Dart异步编程:隔离和事件循环

尽管Dart是一种单线程语言,但它提供了对futures、streams、background工作以及所有其他需要用现代、异步和(对于Flutter而言)反应式编程的内容的支持。本文介绍了Dart对background工作的支持的基础:隔离(isolates )和事件循环(event loops)。

如果您喜欢通过观看或聆听来学习,则以下视频介绍了本文中的所有内容,该视频属于Flutter in Focus视频系列Dart中的异步编程的一部分:

https://youtu.be/vl_AaCgudcY

还在这里吗?我们来谈谈isolates(隔离)。


Isolates(隔离)

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

image-20200828155959330

隔离具有自己的内存和运行事件循环的单个执行线程。

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

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

image-20200828163811048

两个隔离,每个隔离都有自己的内存和执行线程。

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

事实上,隔离能够协同工作的唯一方式是来回传递消息。一个隔离程序向另一个隔离程序发送消息,接收隔离程序使用其事件循环处理该消息。

image-20200828164020962

隔离区可以将消息发送到其他隔离区。

共享内存的缺乏可能听起来有点严格,特别是如果您来自Java或c++这样的语言,但它对Dart编码人员有一些关键的好处。

例如,一个隔离中的内存分配和垃圾收集不需要锁定。只有一个线程,所以如果它不忙,您就知道内存没有发生变化。这对于Flutter应用来说非常有效,因为它有时需要快速构建和拆除一堆小部件。


事件循环

现在,您已经对隔离有了基本的介绍,让我们深入研究真正使异步代码成为可能的东西:事件循环。

想象一下应用程序的寿命在时间轴上延伸。 该应用程序启动,该应用程序停止,并且在一系列事件之间发生–来自磁盘的I / O,来自用户的手指敲击……各种各样的东西。

您的应用程序无法预测这些事件何时或以何种顺序发生,它必须用一个永不会阻塞的线程来处理所有这些事件。app运行一个事件循环。它从它的事件队列中获取最老的事件,处理它,然后返回到下一个,处理它,以此类推,直到事件队列为空。

应用程序在整个运行过程中-您在屏幕上点击,下载内容,计时器关闭-该事件循环不断循环,一次处理一次这些事件。

image-20200828164457227

事件循环一次处理一个事件。

当操作中断时,线程就挂起,等待下一个事件。它可以触发垃圾收集器,喝点咖啡什么的。

所有Dart用于异步编程的高级api和语言特性—futures、流、异步和等待——都建立在这个简单的循环之上。

例如,假设您有一个启动网络请求的按钮,如下所示:


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

当您运行应用程序时,Flutter会构建按钮并将其显示在屏幕上。 然后您的应用程序等待。

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

该事件被选中进行处理。Flutter看着它,渲染系统说,“那些坐标匹配凸起的按钮,”所以Flutter执行onPressed函数。该代码启动一个网络请求(返回一个future),并使用then()方法为future注册一个完成处理程序。

就是这样。 循环完成了对点击事件的处理,并将其丢弃。

onPressed是RaisedButton的一个属性,网络事件使用了future的回调,但这两种技术做的是相同的基本事情。它们都是一种告诉Flutter的方式,“嘿,稍后,你可能会看到一个特定类型的事件。当你这样做时,请执行这段代码。”

因此,onPressed正在等待点击,而future正在等待网络数据,但是从Dart的角度来看,这些都只是队列中的事件。

这就是在Dart中异步编码的工作方式。Futures, streams, async和await——这些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》

要了解关于Dart中异步的更多信息,请参阅本系列的下一篇文章:Dart异步编程:Futures

以上就是Dart异步编程:隔离和事件循环全部内容,感谢大家支持自学php网。

最新评论

添加评论

自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习

京ICP备14009008号-1@版权所有www.zixuephp.com

网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com

添加评论