Flutter Dart语言(05)异步

0 说明

该系列教程主要是为有一定语言基础 C/C++的程序员,快速学习一门新语言所采用的方法,属于在C/C++基础上扩展新语言的模式。

1 async和await

在Dart语言中,虽然没有像其他语言(如Java、C++、Python)中的传统多线程概念,但它采用了异步(asynchronous)编程模型来处理并发任务。Dart使用async和await关键字来支持异步操作,这可以在很大程度上达到类似多线程的效果,但实际上是基于单线程的事件循环机制。

异步主要涉及2个关键词:async和await。async 是让方法变成异步,await是等待异步方法执行完。两个关键字的约束如下:

  • 只有async方法才能使用await关键字去调用方法。
  • 如果调用别的async方法必须使用await关键字。

这里以一个http服务为例来解读这两个关键字的使用,代码如下所示:

Dart 复制代码
import 'dart:convert';
import 'package:http/http.dart' as http;

void main() async {
  // 发起HTTP GET请求
  final response = await http.get(
        Uri.parse('https://jsonplaceholder.typicode.com/posts/1'));

  if (response.statusCode == 200) {
    final responseData = json.decode(response.body);
    print('Title: ${responseData['title']}');
    print('Body: ${responseData['body']}');
  } else {
    print('Request failed with status: ${response.statusCode}');
  }
}

2 隔离 Isolate机制

在Dart中本身是没有多进程概念的,但可以使用Isolate隔离机制来实现多进程效果。Isolate是一种轻量级的并发执行单元,可以在不同的线程中运行代码(说明:每个isolate 都有一个完整的事件循环机制,每个隔离区都有自己的内存堆,确保每个隔离区的状态都不会被其他隔离区访问,隔离这种机制更像是进城而非线程)。这里制作一个demo,模拟 主线程循环输出aaa,子线程循环输出bbb,各输出5次,代码实现如下所示:

Dart 复制代码
import 'dart:isolate';

void main() {
  startChildIsolate();

  for (var i = 0; i < 5; i++) {
    print("aaa");
    sleep(Duration(seconds: 1));
  }
}

void startChildIsolate() async {
  final isolate = await Isolate.spawn(childIsolate, null);
}

void childIsolate(dynamic message) {
  for (var i = 0; i < 5; i++) {
    print("bbb");
    sleep(Duration(seconds: 1));
  }
}

命令执行效果如下所示:

bash 复制代码
Connecting to VM Service at ws://127.0.0.1:59390/qHZyzE0WjeQ=/ws
aaa
bbb
aaa
bbb
aaa
bbb
aaa
bbb
---------

3 Isolate 隔离-双向通讯

这里主要通过Isolate机制构建了一个主线程和一个子线程并进行双向通信,主要使用SendPort和ReceivePort。代码实现如下:

Dart 复制代码
import 'dart:isolate';

var anotherIsolate;

void startMainIsolate() async {
  var receivePort = ReceivePort();
  var sendPort;

  anotherIsolate = await Isolate.spawn(threadIsolateInit, receivePort.sendPort);

  receivePort.listen((date) {
    if (date is SendPort) {
      sendPort = date;
      print("双向通讯建立成功");
      return;
    }
    print("主线程 接收消息:data = $date");
    sendPort.send("XXXXX");
  });
}

void threadIsolateInit(SendPort sendPort) async {

  var receivePort = ReceivePort();
  print("子线程 接受到来自 主线程的port,尝试建立同主线程的双向通讯");

  receivePort.listen((date) {
    print("子线程接收消息:data = $date");
  });

  sendPort.send(receivePort.sendPort);

  for (var index = 0; index < 10; index++) {
    sendPort.send("子线程 发送消息:$index");
  }
}

void main() {
  startMainIsolate();
}

运行效果如下:

bash 复制代码
onnecting to VM Service at ws://127.0.0.1:60037/CvPyFfwECy8=/ws
子线程 接受到来自 主线程的port,尝试建立同主线程的双向通讯
双向通讯建立成功
主线程 接收消息:data = 子线程 发送消息:0
主线程 接收消息:data = 子线程 发送消息:1
主线程 接收消息:data = 子线程 发送消息:2
主线程 接收消息:data = 子线程 发送消息:3
子线程接收消息:data = XXXXX
主线程 接收消息:data = 子线程 发送消息:4
子线程接收消息:data = XXXXX
主线程 接收消息:data = 子线程 发送消息:5
子线程接收消息:data = XXXXX
主线程 接收消息:data = 子线程 发送消息:6
子线程接收消息:data = XXXXX
主线程 接收消息:data = 子线程 发送消息:7
子线程接收消息:data = XXXXX
主线程 接收消息:data = 子线程 发送消息:8
子线程接收消息:data = XXXXX
主线程 接收消息:data = 子线程 发送消息:9
子线程接收消息:data = XXXXX
子线程接收消息:data = XXXXX
子线程接收消息:data = XXXXX
子线程接收消息:data = XXXXX
相关推荐
火柴就是我2 小时前
flutter 之真手势冲突处理
android·flutter
Speed1232 小时前
`mockito` 的核心“打桩”规则
flutter·dart
法的空间2 小时前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
恋猫de小郭3 小时前
Android 将强制应用使用主题图标,你怎么看?
android·前端·flutter
玲珑Felone3 小时前
从flutter源码看其渲染机制
android·flutter
ALLIN1 天前
Flutter 三种方式实现页面切换后保持原页面状态
flutter
Dabei1 天前
Flutter 国际化
flutter
Dabei1 天前
Flutter MQTT 通信文档
flutter
Dabei1 天前
Flutter 中实现 TCP 通信
flutter
孤鸿玉1 天前
ios flutter_echarts 不在当前屏幕 白屏修复
flutter