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
相关推荐
君蓦4 小时前
Flutter 本地存储与数据库的使用和优化
flutter
problc14 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter
lqj_本人1 天前
鸿蒙next选择 Flutter 开发跨平台应用的原因
flutter·华为·harmonyos
lqj_本人1 天前
Flutter&鸿蒙next 状态管理框架对比分析
flutter·华为·harmonyos
起司锅仔1 天前
Flutter启动流程(2)
flutter
hello world smile1 天前
最全的Flutter中pubspec.yaml及其yaml 语法的使用说明
android·前端·javascript·flutter·dart·yaml·pubspec.yaml
lqj_本人1 天前
Flutter 的 Widget 概述与常用 Widgets 与鸿蒙 Next 的对比
flutter·harmonyos
iFlyCai1 天前
极简实现酷炫动效:Flutter隐式动画指南第二篇之一些酷炫的隐式动画效果
flutter
lqj_本人1 天前
Flutter&鸿蒙next 中使用 MobX 进行状态管理
flutter·华为·harmonyos