Dart中如何等待所有void类型downloadfile执行完成后调用encode()
问题:等待所有异步下载完成后执行后续函数
现有Dart代码中main函数已声明为async,先通过await get_vid()获取字符串列表urld。原本通过urld.asMap().forEach调用void类型的downloadfile函数,需求是等所有downloadfile执行完毕后再执行encode()函数。尝试用await Future.wait实现但未成功,该如何处理?
代码示例:
void main() async { List<String> urld; urld = await get_vid(); await Future.wait(urld.asMap(), (i, s) async {await downloadfile(s, i.toString());}) // 无法正常工作 urld.asMap().forEach((i, s) {downloadfile(s, i.toString());}); // 原代码 encode(); // 需在所有downloadfile线程完成后执行 }
解决方案
你使用Future.wait的方式有误,Future.wait要求传入一个**Iterable<Future>类型的集合**,而不是直接传Map,也不支持第二个回调参数。要实现等待所有下载完成,核心是把每个downloadfile调用包装成Future,再用Future.wait等待全部完成。
正确实现方式
首先确认downloadfile的类型:
- 如果
downloadfile本身是异步函数(返回Future<void>),直接收集它的返回值即可; - 如果
downloadfile是同步函数,需要用Future.run包裹调用,将同步操作转为异步任务。
写法一:用for循环生成任务列表
void main() async { List<String> urld = await get_vid(); // 收集所有下载任务的Future final downloadTasks = <Future<void>>[]; for (int index = 0; index < urld.length; index++) { final url = urld[index]; // 根据downloadfile类型选择对应写法 downloadTasks.add(downloadfile(url, index.toString())); // 若为同步函数则替换为: // downloadTasks.add(Future.run(() => downloadfile(url, index.toString()))); } // 等待所有下载任务完成 await Future.wait(downloadTasks); // 所有下载完成后执行encode encode(); }
写法二:用map简化生成任务列表
void main() async { List<String> urld = await get_vid(); await Future.wait( urld.asMap().entries.map((entry) async { final index = entry.key; final url = entry.value; await downloadfile(url, index.toString()); // 同步函数则替换为: // await Future.run(() => downloadfile(url, index.toString())); }) ); encode(); }
关键说明
urld.asMap().entries可以同时获取每个元素的索引和值,方便传递给downloadfile;Future.wait会阻塞直到传入的所有Future都执行完毕,之后才会执行encode();- 必须确保每个下载操作都被包装成
Future,否则Future.wait无法追踪任务状态。
内容的提问来源于stack exchange,提问作者Laura Bieber
相关产品推荐
相关产品推荐

