Dart 异步编程之 Isolate 和事件循环。
Dart 异步编程之 Isolate 和事件循环。
尽管 Dart 是个单线程任务,但它提供 Future、Stream、后台任务以及其他特性用于编写现代异步程序以及响应式程序(Flutter)。本文讲的是 Dart 后台任务的基础:Isolate 和事件循环。
我们先从 Isolate 开始。
Isolates
大多数应用程序中,线程的数量都不止一个。多个线程可以互不干扰地并发执行,并共享进程的全局变量和堆的数据。 线程的访问非常自由,它可以访问进程内存里的所有数据,甚至包括其他线程的堆栈 《程序员的自我修养》
所有的 Dart 代码都运行在 Isolate 中。Isolate 有自己私有的内存空间和一个基于事件循环的线程。
Two isolates, each with its own memory and thread of execution.
新创建的 Isolate 有自己的事件循环和内存,原先的 Isolate (即创建新 Isolate 的那个 Isolate) 不能访问这些内存。这种机制正是 Isolate 名字的来源:内存块之间彼此隔离。
事实上,Isolate 之间能协作的唯一方式是消息传递。一个 Isolate 可以向另一个 Isolate 发送消息,接收方在其事件循环处理收到的消息。
The event loop processes one event at a time.
事件循环空闲时,线程会暂停并循环下一个事件。这时可能触发垃圾回收器等等。Dart 为异步编程提供的所有高级 API 和语言特性,如 Future、Stream、async/await,都是基于和围绕这个基本的循环。
比如,某个按钮用于发起网络请求,就像这样:
RaisedButton( child: Text('Click me'), onPressed: () { final myFuture = http.get('https://example.com'); myFuture.then((response) { if (response.statusCode == 200) { print('Success!'); } }); }, )
你运行应用时,Flutter 构建按钮并显示到屏幕,之后应用开始等待。
应用的事件循环处于空闲,等待下一个事件。当按钮等待点击时,跟按钮不相关的事件可能发生并进入到事件队列被处理。当点击事件发生时,最终会进入队列。
点击事件被取到,等待处理。Flutter 看到这个事件,它的渲染系统说 “事件坐标跟 RaisedButton 匹配”,所以 Flutter 执行 onPressed 函数。这个函数会发起网络请求(返回一个 Future)并使用
then() 方法注册 completion handler。
整个过程就是这样的。事件循环处理完点击事件后将其抛弃。
onPressed 是 RaisedButton 的一个属性,而网络事件为 Future 添加了一个回调,但两者都是在相同的基本操作。它们都是在告诉 Flutter,”你好,一会儿将发生某个事件,你记得执行该事件的代码。”
onPressed 在等待点击,而 Future 在等待网络数据,从 Dart 的视角,这些都是队列中的事件。
这也正是 Dart 中异步代码的工作方式。Future、Steam、以及 async/await,这些 API 都是你告诉 Dart 事件循环执行代码的一种方式。
如果再来回头看刚才的例子,你可以准确地看到它是如何为特定的事件被分解成一小块一小块的。
- 初始的 UI 构建事件
- 点击事件
- 网络响应事件
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 中的 Isolate、事件循环以及异步编程基础。
最后
这里也为想要学习Flutter的朋友们准备了两份学习资料《Flutter Dart语言编程入门到精通》《Flutter实战》,从编程语言到项目实战,一条龙服务!!
《Flutter Dart 语言编程入门到精通》
- 第一章 Dart语言基础
- 第二章 Dart 异步编程
- 第五章 Dart 网络编程
- 第六章 Flutter 爬虫与服务端
《Flutter实战:第二版》
- 第一章:起步
- 第二章:第一个Flutter应用
- 第三章:基础组件
- 第四章:布局类组件
- 第五章:容器类组件