异步函数中为何无法使用forEach?与for循环的执行差异疑问
为什么异步函数中forEach无法替代for循环?
核心原因很简单:forEach的闭包不支持异步操作,而for-in循环可以直接在异步函数内部使用await。
先看你的代码场景
获取文档列表的基础代码:
let query = try? await store.collection("feedposts").getDocuments() let documents = query?.documents ?? []
有效:for-in循环
for document in documents { try? await store.collection("feedposts").document(document.documentID).collection("locked").document(uid).delete() }
for-in循环是在异步函数的上下文里执行的,每次迭代都会等待await标记的异步删除操作完成后,再进入下一次循环,所有操作按顺序执行,逻辑完全符合预期。
无效:forEach
documents.forEach { document in try? await store.collection("feedposts").document(document.documentID).collection("locked").document(uid).delete() }
问题出在forEach的设计上:它接收的闭包类型是(Element) -> Void,也就是同步闭包,你没办法给这个闭包加上async关键字。强行在闭包里使用await会导致编译错误(就算用try?掩盖错误,运行时也不会等待异步任务完成,甚至可能根本不会执行这些删除操作)。
解决办法
如果你想要类似forEach的写法同时支持异步操作,可以自定义一个异步遍历的扩展方法:
extension Sequence { func asyncForEach(_ operation: (Element) async throws -> Void) async rethrows { for element in self { try await operation(element) } } }
使用方式和forEach几乎一致,但支持异步:
try? await documents.asyncForEach { document in await store.collection("feedposts").document(document.documentID).collection("locked").document(uid).delete() }
如果不需要按顺序执行删除操作(想要并发提升效率),可以用任务组:
await withTaskGroup(of: Void.self) { group in for document in documents { group.addTask { try? await store.collection("feedposts").document(document.documentID).collection("locked").document(uid).delete() } } }
内容的提问来源于stack exchange,提问作者AdamLeet
相关产品推荐
相关产品推荐

