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
相关产品推荐
相关产品推荐

