意义:异步编程是一种非阻塞的,事件驱动的编程机制。异步编程可以充分利用系统资源来并行执行多个任务,提高系统的运行效率。
异步函数:指的是被async标识符标记的函数,该函数会返回Future对象。
常见的创建Future的函数:
①Future():默认构造函数,返回值可以是普通值或Future对象。
②Future.microtask():将Future对象添加到异步任务队列。
③Future.sync():创建一个同步任务,该任务会被立即执行
④Future.delayed():创建一个延时任务,但是延时不一定准确
⑤Future.error():创建一个Future对象,返回结果为错误
在异步任务中,Future中的任务完成后还需要添加一个回调函数,用于处理回调的结果,并且回调会被立即执行。
1.Future基础
Dart
//定义一个Future函数
Future<String> fetchUserOrder() {
// 模拟网络请求延迟
return Future.delayed(Duration(seconds: 2), () => 'Large Latte');
}
void main() {
print('开始获取订单...');
fetchUserOrder().then((order) {
print('您的订单: $order');
}).catchError((error) {
print('出错: $error');
});
print('继续执行其他操作...');
}
执行结果
Dart
开始获取订单...
继续执行其他操作...
(2秒后输出)您的订单: Large Latte
数据流时间线
Dart
时间轴: 0秒 → 立即执行 → 2秒后
↓ ↓ ↓
main()开始执行
↓
print('开始获取订单...') → 输出: "开始获取订单..."
↓
fetchUserOrder()被调用 → 启动2秒计时器,立即返回Future对象
↓
.then()注册回调函数 → 告诉Future:"完成后调用这个函数"
↓
.catchError()注册错误处理 → 告诉Future:"出错时调用这个函数"
↓
print('继续执行...') → 输出: "继续执行其他操作..."
↓
╭─ 主线程空闲,可以处理其他事情 ─╮
│ 等待2秒钟... │
╰─────────────────────╯
↓
2秒时间到!Future完成
↓
() => 'Large Latte'执行 → 返回字符串'Large Latte'
↓
.then((order) {...})执行 → order = 'Large Latte'
↓
print('您的订单: $order') → 输出: "您的订单: Large Latte"
可视化流程图
Dart
┌─────────────────┐ 同步执行 ┌──────────────────┐
│ main()开始 │ ────────────> │ 打印"开始获取订单" │
└─────────────────┘ └──────────────────┘
│
│ 调用fetchUserOrder()
▼
┌─────────────────┐ 立即返回 ┌──────────────────┐
│ 创建Future对象 │ ────────────> │ 注册.then回调 │
│ 启动2秒计时器 │ └──────────────────┘
└─────────────────┘
│
│ 不等待,继续执行
▼
┌─────────────────┐ 同步执行 ┌──────────────────┐
│ 打印"继续执行..." │ ────────────> │ 输出到控制台 │
└─────────────────┘ └──────────────────┘
│
╰─ 主线程空闲 ────────────┐
│ 等待2秒...
▼
┌─────────────────┐
│ 2秒时间到! │
│ Future完成 │
└─────────────────┘
│
│ 执行回调函数
▼
┌─────────────────┐ 异步回调 ┌──────────────────┐
│ .then()被调用 │ <──────────── │ 传入'Large Latte' │
└─────────────────┘ └──────────────────┘
│
│ 执行打印
▼
┌─────────────────┐ 同步执行 ┌──────────────────┐
│ 打印"您的订单..." │ ────────────> │ 输出到控制台 │
└─────────────────┘ └──────────────────┘
.then(order)里面的order代表什么?
order就是 Future.delayed 里面那个函数返回的东西:
Dart
Future<String> fetchUserOrder() {
return Future.delayed(Duration(seconds: 2), () => 'Large Latte');
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
// 这个函数的返回值就是order!
}
order数据传递路径
Dart
() => 'Large Latte' // 这个函数返回字符串
↓
Future完成,携带结果
↓
.then((order) { ... }) // order = 'Large Latte'
2.Future的三种状态
Dart
void futureStates() {
// 1. 未完成 (uncompleted)
var future = fetchUserOrder();
// 2. 完成带有值 (completed with value)
future.then((value) => print('成功: $value'));
// 3. 完成带有错误 (completed with error)
future.catchError((error) => print('失败: $error'));
}
3.Future常用方法
Dart
void futureMethods() {
// Future.value - 立即完成的Future
Future.value('立即返回值').then(print);
// Future.error - 立即返回错误的Future
Future.error('错误信息').catchError(print);
// Future.delayed - 延迟执行
Future.delayed(Duration(seconds: 1), () => '延迟返回').then(print);
// Future.wait - 等待多个Future完成
Future.wait([
Future.delayed(Duration(seconds: 1), () => '结果1'),
Future.delayed(Duration(seconds: 2), () => '结果2'),
]).then((results) {
print(results); // ['结果1', '结果2']
});
}
4.async/await 语法糖
规则:
有 await 就必须有 async
await 会"阻塞"当前函数(不会阻塞整个程序)
基本用法
Dart
// 使用 async 标记异步函数
Future<String> fetchUserOrder() async {
// 使用 await 等待异步操作完成
var order = await Future.delayed(
Duration(seconds: 2),
() => 'Large Latte'
);
return order;
}
void main() async {
print('开始获取订单...');
try {
// await 就是告诉程序:"停在这里等,直到拿到结果再继续"
var order = await fetchUserOrder();// ⏸️ 程序在这里暂停2秒
print('您的订单: $order');// ▶️ 2秒后继续执行
} catch (error) {
print('出错: $error');
}
print('继续执行其他操作...');// 🔄 然后执行这行
}
输出结果
Dart
开始获取订单...
(等待2秒...)
您的订单: Large Latte
继续执行其他操作...
完整数据流时间线
Dart
时间轴: 0秒 → 2秒等待期间 → 2秒后
↓ ↓ ↓
main()开始执行
↓
print('开始获取订单...') → 输出: "开始获取订单..."
↓
遇到await fetchUserOrder()
↓
执行fetchUserOrder()函数
↓
遇到await Future.delayed()
↓
╭─ main()函数在此暂停 ────────╮
│ 等待2秒钟... │
│ (但UI线程不被阻塞) │
╰─────────────────────╯
↓
2秒时间到!Future.delayed完成
↓
() => 'Large Latte'执行 → 返回'Large Latte'
↓
fetchUserOrder()恢复执行 → order = 'Large Latte'
↓
fetchUserOrder()返回'Large Latte'
↓
main()函数恢复执行 → order = 'Large Latte'
↓
print('您的订单: $order') → 输出: "您的订单: Large Latte"
↓
print('继续执行其他操作...') → 输出: "继续执行其他操作..."
可视化执行数据
Dart
┌─────────────────┐ 同步执行 ┌──────────────────┐
│ main()开始 │ ────────────> │ 打印"开始获取订单" │
└─────────────────┘ └──────────────────┘
│
│ 遇到await
▼
┌─────────────────┐ 调用 ┌──────────────────┐
│ 执行fetchUserOrder│ ────────────> │ 遇到await delayed │
└─────────────────┘ └──────────────────┘
│ │
│ 两者都暂停 │ 启动2秒计时器
╰────────── 等待2秒 ──────────╯
↓
计时器完成,传递数据
↓
┌─────────────────┐ 恢复 ┌──────────────────┐
│ fetchUserOrder │ <──────────── │ 返回'Large Latte' │
│ 恢复执行 │ └──────────────────┘
└─────────────────┘
│
│ 返回结果
▼
┌─────────────────┐ 恢复 ┌──────────────────┐
│ main()恢复执行 │ <──────────── │ 收到'Large Latte' │
└─────────────────┘ └──────────────────┘
│
├─ 打印"您的订单: Large Latte"
│
└─ 打印"继续执行其他操作..."