⚡ 什么是异步编程?

想象一下异步编程就像是:

  • 餐厅点餐:你点完餐后不需要站在厨房门口等待,可以坐下聊天,菜好了服务员会通知你
  • 洗衣服:你把衣服放进洗衣机后,可以去做其他事情,洗好了机器会提醒你
  • 网上购物:下单后不需要一直盯着物流,快递到了会有通知

在Flutter中,异步编程让我们的应用能够在等待耗时操作(如网络请求、文件读写)时不会卡住,用户界面依然流畅响应。


🔮Future深入理解 - 未来的承诺

1.1 理解Future

Future就像是一张"未来支票",现在给你一个承诺,将来某个时候会兑现(成功或失败)。
在这里插入图片描述

1.2 Future的书写方法 📚

🌟 生活场景类比

想象你去咖啡店点咖啡:

  1. 同步方式 (传统方式) ☕

    • 你站在柜台前等待
    • 咖啡师开始制作咖啡
    • 你一直站着等,什么都不能做
    • 咖啡做好了,你拿到咖啡
    • 你才能继续做其他事情
  2. 异步方式 (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 较少使用 封装异步操作
🔑 关键要点
  1. Future是什么?

    • 一个"承诺",代表将来会完成的操作
    • 就像咖啡店的号码牌、网购的订单号
  2. 为什么用Future?

    • 不阻塞程序运行
    • 可以同时做多件事
    • 让应用保持流畅
  3. 怎么选择书写方法?

    • 简单操作 → then()
    • 复杂流程 → async/await
    • 创建Future → 构造函数
  4. 记住这个公式:

    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! 🚀

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新

更多推荐