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

Dart异步函数如何等待Stream流处理完成后再返回medias列表

问题根因

你当前代码提前返回的核心是没有等待异步回调执行完成:

  • fileDownloadFuntion调用后使用了.then()非阻塞回调,函数不会等待下载完成就会向后执行
  • Stream流的listen监听逻辑属于异步回调,onDone执行前函数不会阻塞等待
  • 文件写入方法writeAsBytes本身是异步接口,原代码未加等待逻辑,文件写入完成前逻辑就会继续向下走

修正后完整代码

Future<List<Media>> getVideo(var _client, var _videofolder) async {
  final pathContext = path.Context(style: path.Style.windows);
  var tempDir = await getTemporaryDirectory();
  String tempPath = tempDir.path;

  print(tempPath);

  final filePath = pathContext.join(tempPath, _videofolder[videoNumber]["name"]);
  final targetFile = io.File(filePath);

  if (!await targetFile.exists()) {
    print("file does not exist yet");
    // 等待下载请求返回响应
    final response = await drive.fileDownloadFuntion(_videofolder[videoNumber]["id"], _client);
    print("file downloaded");
    // 等待流全部读取完成,拿到完整字节数据
    final byteList = await response.stream.toBytes();
    final saveFile = io.File(filePath);
    // 等待文件写入本地磁盘完成
    await saveFile.writeAsBytes(byteList);
    print("File saved at ${saveFile.path}");

    if (await saveFile.exists()) {
      medias.add(
        Media.file(io.File(filePath.replaceAll('"', ''))),
      );
    }
  } else {
    print("file exists");
    if (await targetFile.exists()) {
      medias.add(
        Media.file(io.File(filePath.replaceAll('"', ''))),
      );
    }
  }
  // 所有逻辑处理完成后再更新计数、返回结果
  videoNumber++;
  return medias;
}

核心修改说明

  • 把.then()回调改为await调用,保证下载完成后才执行后续逻辑
  • 使用Dart Stream内置的toBytes()异步方法替代手动监听流的逻辑,自动等待流处理完成再返回完整字节
  • 给writeAsBytes方法添加await,等待本地文件写入完成后再执行后续添加媒体到列表的操作
  • 所有异步逻辑都等待完成后再执行videoNumber累加和结果返回,保证返回的medias列表已经包含本次处理的媒体文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 09:09:03