Dart 3 Record:解决 Future.wait 异构返回值的类型问题

在 Flutter 开发中,经常会遇到多个接口需要同时请求的场景。

例如进入图书详情页时,需要同时获取书籍信息和收藏状态:

ini 复制代码
final infoFuture = bookApi.getBookInfo(bookId);
final favoriteFuture = favoriteApi.isFavorite(bookId);

两个请求互不依赖,可以使用 Future.wait:

ini 复制代码
final responses = await Future.wait([
  infoFuture,
  favoriteFuture,
]);

这种写法可以并发等待多个 Future,但当这些 Future 的返回类型不同时,会出现一个问题:结果列表无法保留每个元素原本的具体类型。

Future.wait 的类型问题

假设两个请求的返回类型分别是:

ini 复制代码
Future<BookInfo> infoFuture;
Future<bool> favoriteFuture;

我们使用:

ini 复制代码
final responses = await Future.wait([
  infoFuture,
  favoriteFuture,
]);

两个 Future 返回的类型不同:

arduino 复制代码
BookInfo
bool

但 Future.wait 最终返回的是一个 List。

这时无法得到类似:

arduino 复制代码
List<BookInfo, bool>

这样的类型。

因此,实际使用时通常需要进行类型转换:

ini 复制代码
final bookInfo = responses[0] as BookInfo;
final isFavorite = responses[1] as bool;

完整代码:

ini 复制代码
final responses = await Future.wait([
  infoFuture,
  favoriteFuture,
]);

final bookInfo = responses[0] as BookInfo;
final isFavorite = responses[1] as bool;

代码能运行,但有两个问题。

第一,需要自己记住 responses[0] 和 responses[1] 分别是什么。

第二,需要手动使用 as 转换类型。

当 Future 增多后:

ini 复制代码
final results = await Future.wait([
  bookFuture,
  favoriteFuture,
  commentsFuture,
  authorFuture,
]);

后面就会出现:

ini 复制代码
final book = results[0] as Book;
final favorite = results[1] as bool;
final comments = results[2] as List<Comment>;
final author = results[3] as Author;

这不仅不直观,也失去了 Dart 静态类型系统带来的便利。

Dart 3 使用 Record 保留类型

如果项目使用 Dart 3,可以使用 Record。

把原来的:

ini 复制代码
final responses = await Future.wait([
  infoFuture,
  favoriteFuture,
]);

改成:

scss 复制代码
final (bookInfo, isFavorite) = await (
  infoFuture,
  favoriteFuture,
).wait;

这里的两个 Future 仍然会并发执行。

区别在于,Record 可以保留每个位置对应的具体类型。

也就是说:

scss 复制代码
final (bookInfo, isFavorite) = await (
  infoFuture,
  favoriteFuture,
).wait;

得到的变量类型分别是:

arduino 复制代码
bookInfo   → BookInfo
isFavorite → bool

不需要再写:

csharp 复制代码
as BookInfo
as bool

也不需要通过:

css 复制代码
results[0]
results[1]

访问结果。

相关推荐
Seraphina361 小时前
DVWA(XSS Reflected/Stored High,CSRF Low)
前端·xss·csrf
默_笙2 小时前
🍔 中间件不只是打日志:四个钩子、一次短路,和自带的工具
前端·javascript
程序员老赵2 小时前
Docker 部署 Dolibarr:轻松搭建开源 ERP/CRM 平台
运维·前端·后端
星禾元亨3 小时前
同一件事有三份资料,AI 该信哪一份?冲突判定、优先级链与处置流程
前端·人工智能
伯伯熊勞3 小时前
GetX 巢狀路由教學:用三層 Navigator 做桌面多欄佈局
flutter
Dovis(誓平步青云)3 小时前
家里设备越来越多,如何用一张空间地图控制灯光和温度![
android·java·前端·javascript·人工智能·电脑
穆梓兰煊3 小时前
TS5.7 vs 裸JS:AI应用少3坑
前端
榆瓷3 小时前
闲着没事,我把 WebGPU 的样板代码封成了一个库
前端
136096757233 小时前
页面打不开不是 Nginx 的错
前端·后端