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

Flutter中await调用异步上传函数未等待执行完成的问题

问题原因

await upload()的调用逻辑本身没有问题,bug出在upload函数内部的响应处理环节:

  • response.stream.transform(utf8.decoder).listen()属于非阻塞的流订阅操作,调用listen注册完回调后,代码不会等待回调执行,会直接向下运行到return createdFileName语句
  • 此时响应流还未完成数据解析,createdFileName仍是初始化时的空字符串,函数会直接将空值返回
  • 等后续流读取到服务端返回的文件名、执行回调给createdFileName赋值时,函数早已完成返回,赋值操作无法修改已经返回的结果,最终列表里拿到的全是空值,表现为循环未等待上传完成就进入下一轮迭代。
修复方案

替换非阻塞的listen订阅逻辑,使用await等待响应流完整解析完成后再返回结果,修复后的upload函数代码如下:

Future<String> upload(File imageFile) async {
  var stream = http.ByteStream(DelegatingStream.typed(imageFile.openRead()));
  var length = await imageFile.length();

  var uri = Uri.parse("http://localhost:8080/upload");
  var request = http.MultipartRequest("POST", uri);

  var multipartFile = http.MultipartFile(
    'file',
    stream,
    length,
    filename: basename(imageFile.path)
  );
  request.files.add(multipartFile);

  var response = await request.send();
  print(response.statusCode);
  // 等待响应流完整解码拼接,拿到服务端返回的文件名
  final createdFileName = await response.stream.transform(utf8.decoder).join();
  print(createdFileName);
  return createdFileName;
}

原有循环调用的代码无需修改,修复后循环会按顺序等待每个文件上传完成、拿到正确的文件名后再进入下一轮迭代,createdFileNames列表就能得到正确的返回值。

注:使用join()可以自动拼接响应流的所有分片内容,适配服务端分块返回响应的场景,避免出现文件名截断的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:39:19