Flutter---异步编程

意义:异步编程是一种非阻塞的,事件驱动的编程机制。异步编程可以充分利用系统资源来并行执行多个任务,提高系统的运行效率。

异步函数:指的是被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"
         │
         └─ 打印"继续执行其他操作..."
相关推荐
子兮曰18 小时前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰18 小时前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
小羊没烦恼!19 小时前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
前端小万19 小时前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝19 小时前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋19 小时前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
伞伞悦读20 小时前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
卡布鲁20 小时前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
C语言小火车20 小时前
C/C++ 为什么需要编译器?
开发语言·c++
李少兄21 小时前
JavaScript 隐式全局变量解析
javascript