来源:未知 时间: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中的异步编程的一部分: 还在这里吗?我们来谈谈isolates(隔离)。 Isolates(隔离)隔离是所有Dart代码运行的地方。它就像机器上的一个小空间,有它自己的私有内存块和一个运行事件循环的线程。
在许多其他语言(例如C ++)中,您可以让多个线程共享相同的内存并运行所需的任何代码。 但是,在Dart中,每个线程都处于其自己的隔离区中,并拥有自己的内存,并且该线程仅处理事件(稍后会详细介绍)。 许多Dart应用程序都在单个隔离中运行所有代码,但是如果需要,您可以拥有多个。 如果要执行的计算量如此之大,如果它在主隔离中运行,可能会导致丢帧,那么您可以使用Isolate.spawn()或Flutter的compute()函数。 这两个函数都创建了一个单独的隔离程序来进行数字运算,从而使您的主要隔离程序可以自由地(例如,重建和呈现小部件树)。
新隔离区拥有自己的事件循环和内存,即使原始隔离区是该新隔离区的父级,也不允许其访问。 这就是isolate的名称的来源:这些小空间彼此隔离。 事实上,隔离能够协同工作的唯一方式是来回传递消息。一个隔离程序向另一个隔离程序发送消息,接收隔离程序使用其事件循环处理该消息。
共享内存的缺乏可能听起来有点严格,特别是如果您来自Java或c++这样的语言,但它对Dart编码人员有一些关键的好处。 例如,一个隔离中的内存分配和垃圾收集不需要锁定。只有一个线程,所以如果它不忙,您就知道内存没有发生变化。这对于Flutter应用来说非常有效,因为它有时需要快速构建和拆除一堆小部件。 事件循环现在,您已经对隔离有了基本的介绍,让我们深入研究真正使异步代码成为可能的东西:事件循环。 想象一下应用程序的寿命在时间轴上延伸。 该应用程序启动,该应用程序停止,并且在一系列事件之间发生–来自磁盘的I / O,来自用户的手指敲击……各种各样的东西。 您的应用程序无法预测这些事件何时或以何种顺序发生,它必须用一个永不会阻塞的线程来处理所有这些事件。app运行一个事件循环。它从它的事件队列中获取最老的事件,处理它,然后返回到下一个,处理它,以此类推,直到事件队列为空。 应用程序在整个运行过程中-您在屏幕上点击,下载内容,计时器关闭-该事件循环不断循环,一次处理一次这些事件。
当操作中断时,线程就挂起,等待下一个事件。它可以触发垃圾收集器,喝点咖啡什么的。 所有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