【第四阶段-数据处理与网络】第三章:Future深入理解—未来的承诺
异步编程与Future摘要 异步编程就像生活中的非阻塞场景:点餐后无需等待,洗衣时可做其他事。Flutter中异步操作能保持UI流畅响应耗时任务。 Future是"未来承诺",类似咖啡店的取餐号,有三种使用方式: then()链式调用 - 简单但易形成回调地狱 async/await(推荐) - 代码清晰如同步写法 Future构造函数 - 直接创建异步任务 核心优势: 不阻塞
·
文章目录
⚡ 什么是异步编程?
想象一下异步编程就像是:
- 餐厅点餐:你点完餐后不需要站在厨房门口等待,可以坐下聊天,菜好了服务员会通知你
- 洗衣服:你把衣服放进洗衣机后,可以去做其他事情,洗好了机器会提醒你
- 网上购物:下单后不需要一直盯着物流,快递到了会有通知
在Flutter中,异步编程让我们的应用能够在等待耗时操作(如网络请求、文件读写)时不会卡住,用户界面依然流畅响应。
🔮Future深入理解 - 未来的承诺
1.1 理解Future
Future就像是一张"未来支票",现在给你一个承诺,将来某个时候会兑现(成功或失败)。
1.2 Future的书写方法 📚
🌟 生活场景类比
想象你去咖啡店点咖啡:
-
同步方式 (传统方式) ☕
- 你站在柜台前等待
- 咖啡师开始制作咖啡
- 你一直站着等,什么都不能做
- 咖啡做好了,你拿到咖啡
- 你才能继续做其他事情
-
异步方式 (Future方式) 🎯
- 你点完咖啡,拿到一个取餐号码牌(这就是Future!)
- 你可以去找座位、刷手机、聊天
- 咖啡师在后台制作咖啡
- 咖啡做好了,叫你的号码
- 你去取咖啡(Future完成)
Future就是那个"号码牌" - 它代表一个将来会完成的操作!
📖 Future的三种书写方法
方法一: then() 链式调用 🔗
/// 使用 then() 方法处理Future结果
/// 就像: 拿到号码牌后,告诉服务员"咖啡好了叫我一声"
Future<String> makeCoffee() {
return Future.delayed(
Duration(seconds: 3),
() => '☕ 拿铁咖啡',
);
}
void orderCoffee() {
print('1️⃣ 点咖啡,拿到号码牌');
makeCoffee()
.then((coffee) {
print('3️⃣ 咖啡好了: $coffee');
})
.catchError((error) {
print('❌ 出错了: $error');
})
.whenComplete(() {
print('4️⃣ 交易完成');
});
print('2️⃣ 去找座位刷手机');
}
// 运行结果:
// 1️⃣ 点咖啡,拿到号码牌
// 2️⃣ 去找座位刷手机
// (等待3秒...)
// 3️⃣ 咖啡好了: ☕ 拿铁咖啡
// 4️⃣ 交易完成
生活场景: 你点完咖啡后,告诉服务员"好了叫我",然后你就去做其他事情了。
方法二: async/await 同步风格 ✨ (推荐)
/// 使用 async/await 让异步代码看起来像同步代码
/// 就像: 你决定就站在柜台等,但不会阻塞其他人
Future<void> orderCoffeeAsync() async {
print('1️⃣ 点咖啡,拿到号码牌');
try {
// await 表示"我在这里等待,但不阻塞其他人"
String coffee = await makeCoffee();
print('2️⃣ 咖啡好了: $coffee');
print('3️⃣ 开始享用咖啡');
} catch (error) {
print('❌ 出错了: $error');
} finally {
print('4️⃣ 交易完成');
}
}
// 运行结果:
// 1️⃣ 点咖啡,拿到号码牌
// (等待3秒...)
// 2️⃣ 咖啡好了: ☕ 拿铁咖啡
// 3️⃣ 开始享用咖啡
// 4️⃣ 交易完成
生活场景: 你决定就在柜台等咖啡,但你的等待不会阻塞咖啡店的其他顾客。
方法三: Future构造函数 🏗️
/// 直接创建Future对象
/// 就像: 你自己开咖啡店,给顾客发号码牌
Future<String> makeCustomCoffee() {
return Future(() {
// 模拟制作咖啡的过程
print('👨🍳 咖啡师开始制作...');
return '☕ 特调咖啡';
});
}
// 延迟执行
Future<String> makeCoffeeWithDelay() {
return Future.delayed(
Duration(seconds: 2),
() => '☕ 美式咖啡',
);
}
// 立即返回值
Future<String> getReadyCoffee() {
return Future.value('☕ 速溶咖啡(已经好了)');
}
// 立即返回错误
Future<String> getCoffeeError() {
return Future.error('❌ 咖啡机坏了');
}
🎯 三种方法的对比
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| then() | 链式调用,灵活 | 嵌套多了会形成"回调地狱" | 简单的单次异步操作 |
| async/await | 代码清晰,易读易维护 | 需要在async函数中使用 | 推荐! 复杂的异步流程 |
| 构造函数 | 直接创建Future | 较少使用 | 封装异步操作 |
🔑 关键要点
-
Future是什么?
- 一个"承诺",代表将来会完成的操作
- 就像咖啡店的号码牌、网购的订单号
-
为什么用Future?
- 不阻塞程序运行
- 可以同时做多件事
- 让应用保持流畅
-
怎么选择书写方法?
- 简单操作 →
then() - 复杂流程 →
async/await⭐ - 创建Future → 构造函数
- 简单操作 →
-
记住这个公式:
Future<返回类型> 函数名() async { try { var result = await 异步操作(); return result; } catch (error) { // 处理错误 } }
📝 代码说明
这是一个完整的Future演示应用,展示了以下核心功能:
- 基础Future: 演示最简单的异步延迟操作
- 错误处理: 展示如何捕获和处理Future中的异常
- 超时处理: 演示如何为Future操作设置超时限制
- 并行等待: 使用
Future.wait()同时执行多个Future并等待全部完成 - 任意完成: 使用
Future.any()获取最快完成的Future结果
关键技术点:
- 使用
async/await语法简化异步代码 try-catch-finally进行完整的错误处理setState()更新UI状态Future.delayed()模拟耗时操作
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:math';
void main() {
runApp(MaterialApp(
home: FutureDemo(),
theme: ThemeData(primarySwatch: Colors.blue),
));
}
class FutureDemo extends StatefulWidget {
_FutureDemoState createState() => _FutureDemoState();
}
class _FutureDemoState extends State<FutureDemo> {
String result = '';
bool isLoading = false;
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Future 演示')),
body: Padding(
padding: EdgeInsets.all(16),
child: Column(
children: [
// 按钮区域
Wrap(
spacing: 8,
runSpacing: 8,
children: [
ElevatedButton(
onPressed: isLoading ? null : basicFuture,
child: Text('基础Future'),
),
ElevatedButton(
onPressed: isLoading ? null : futureWithError,
child: Text('错误处理'),
),
ElevatedButton(
onPressed: isLoading ? null : futureTimeout,
child: Text('超时处理'),
),
ElevatedButton(
onPressed: isLoading ? null : futureWait,
child: Text('并行等待'),
),
ElevatedButton(
onPressed: isLoading ? null : futureAny,
child: Text('任意完成'),
),
],
),
SizedBox(height: 20),
// 结果显示
Container(
width: double.infinity,
height: 200,
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
borderRadius: BorderRadius.circular(8),
),
child: isLoading
? Center(child: CircularProgressIndicator())
: SingleChildScrollView(
child: Text(
result.isEmpty ? '点击按钮查看结果' : result,
style: TextStyle(fontFamily: 'monospace'),
),
),
),
],
),
),
);
}
// 基础Future
Future<void> basicFuture() async {
setState(() {
isLoading = true;
result = '';
});
try {
await Future.delayed(Duration(seconds: 2));
setState(() {
result = '基础Future执行成功!\n完成时间: ${DateTime.now()}';
});
} catch (e) {
setState(() {
result = '执行失败: $e';
});
} finally {
setState(() {
isLoading = false;
});
}
}
//运行结果:
//等待2秒后显示:
//基础Future执行成功!
//完成时间: 2025-01-19 16:30:45
// 错误处理
Future<void> futureWithError() async {
setState(() {
isLoading = true;
result = '';
});
try {
await Future.delayed(Duration(seconds: 1));
// 随机成功或失败
if (Random().nextBool()) {
setState(() {
result = '操作成功完成!';
});
} else {
throw Exception('模拟操作失败');
}
} catch (e) {
setState(() {
result = '捕获到错误: $e';
});
} finally {
setState(() {
isLoading = false;
});
}
}
//运行结果
// 情况1 - 成功:
// 操作成功完成!
// 情况2 - 失败:
// 捕获到错误: Exception: 模拟操作失败
// 超时处理
Future<void> futureTimeout() async {
setState(() {
isLoading = true;
result = '';
});
try {
// 5秒操作,3秒超时
await Future.delayed(Duration(seconds: 5))
.timeout(Duration(seconds: 3));
setState(() {
result = '操作完成(未超时)';
});
} on TimeoutException {
setState(() {
result = '操作超时!';
});
} catch (e) {
setState(() {
result = '其他错误: $e';
});
} finally {
setState(() {
isLoading = false;
});
}
}
//操作结果
//等待3秒后显示:
//操作超时!
//(因为5秒的操作被3秒超时限制中断)
// 并行等待
Future<void> futureWait() async {
setState(() {
isLoading = true;
result = '';
});
try {
final futures = [
Future.delayed(Duration(seconds: 1), () => '任务A完成'),
Future.delayed(Duration(seconds: 2), () => '任务B完成'),
Future.delayed(Duration(seconds: 3), () => '任务C完成'),
];
final results = await Future.wait(futures);
setState(() {
result = '所有任务完成:\n${results.join('\n')}';
});
} catch (e) {
setState(() {
result = '并行执行失败: $e';
});
} finally {
setState(() {
isLoading = false;
});
}
}
//操作结果
//等待3秒后(最长任务的时间)显示:
//所有任务完成:
//任务A完成
//任务B完成
//任务C完成
// 任意完成
Future<void> futureAny() async {
setState(() {
isLoading = true;
result = '';
});
try {
final futures = [
Future.delayed(Duration(seconds: 3), () => '慢任务'),
Future.delayed(Duration(seconds: 1), () => '快任务'),
Future.delayed(Duration(seconds: 2), () => '中等任务'),
];
final result = await Future.any(futures);
setState(() {
this.result = '最快完成: $result';
});
} catch (e) {
setState(() {
result = '执行失败: $e';
});
} finally {
setState(() {
isLoading = false;
});
}
}
//操作结果
//等待1秒后(最快任务的时间)显示:
//最快完成: 快任务
}
💡 学习要点:
- Future.wait() 会等待所有任务完成,总耗时等于最长任务的时间
- Future.any() 只等待最快的任务,其他任务会继QUARTER-CFE9-ABFC-6356续执行但结果被忽略
- 超时处理可以防止操作无限期等待
- 错误处理确保应用不会因异常而崩溃
Happy Future! 🚀
更多推荐



所有评论(0)