You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart异步函数返回多值:如何在FutureBuilder中使用双结果

Dart异步函数返回多值适配FutureBuilder方案

首先纠正原代码的一个问题:你调用loadUserData(data: data);时没有加await,这会导致该异步操作在后台执行,你无法获取它的返回值,甚至可能在getPowDataActive完成前还没执行完毕,导致数据不一致。

要在FutureBuilder中同时使用两个异步函数的结果,必须将两个返回值合并为一个对象返回,因为FutureBuilder只能绑定单个Future。下面提供几种可行的实现方式:

方式1:使用Tuple(需依赖tuple包)

先在pubspec.yaml中添加依赖:

dependencies:
  tuple: ^2.0.2

修改异步函数,同时等待两个操作完成并返回Tuple:

import 'package:tuple/tuple.dart';

Future<Tuple2<Map, Map>> loadAllData({required Map data, required String detailId}) async {
  final userData = await loadUserData(data: data);
  final powData = await Database.getPowDataActive(detailId: detailId);
  return Tuple2(userData, powData);
}

在FutureBuilder中使用:

FutureBuilder<Tuple2<Map, Map>>(
  future: loadAllData(data: yourData, detailId: yourDetailId),
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      final userData = snapshot.data!.item1;
      final powData = snapshot.data!.item2;
      // 基于两个数据构建UI
      return YourWidget(userData: userData, powData: powData);
    } else if (snapshot.hasError) {
      return const Text('加载失败');
    }
    return const CircularProgressIndicator();
  },
)

方式2:使用自定义数据类

这种方式可读性更强,适合复杂场景:

// 定义存储两个数据的类
class LoadedData {
  final Map userData;
  final Map powData;

  LoadedData({required this.userData, required this.powData});
}

// 修改异步函数
Future<LoadedData> loadAllData({required Map data, required String detailId}) async {
  final userData = await loadUserData(data: data);
  final powData = await Database.getPowDataActive(detailId: detailId);
  return LoadedData(userData: userData, powData: powData);
}

FutureBuilder中使用:

FutureBuilder<LoadedData>(
  future: loadAllData(data: yourData, detailId: yourDetailId),
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      final userData = snapshot.data!.userData;
      final powData = snapshot.data!.powData;
      // 构建UI
      return YourWidget(userData: userData, powData: powData);
    } else if (snapshot.hasError) {
      return const Text('加载失败');
    }
    return const CircularProgressIndicator();
  },
)

方式3:直接返回Map(快速实现,可读性稍弱)

如果不想额外定义类或引入包,可以直接返回包含两个数据的Map:

Future<Map<String, Map>> loadAllData({required Map data, required String detailId}) async {
  final userData = await loadUserData(data: data);
  final powData = await Database.getPowDataActive(detailId: detailId);
  return {'userData': userData, 'powData': powData};
}

FutureBuilder中使用:

FutureBuilder<Map<String, Map>>(
  future: loadAllData(data: yourData, detailId: yourDetailId),
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      final userData = snapshot.data!['userData']!;
      final powData = snapshot.data!['powData']!;
      // 构建UI
      return YourWidget(userData: userData, powData: powData);
    } else if (snapshot.hasError) {
      return const Text('加载失败');
    }
    return const CircularProgressIndicator();
  },
)

关键说明

  • 必须确保两个异步操作都用await等待完成,否则会出现数据未加载完全就返回的情况。
  • FutureBuilder只能监听单个Future,因此必须将多个异步结果合并为一个返回值,无法直接分别获取两个独立Future的快照。

内容的提问来源于stack exchange,提问作者Kim San

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:16:12