Swift中如何在while循环内等待直至触发继续执行?
问题分析与解决方案
你的核心问题在于网络请求是异步执行的,而你用的while是同步循环——这会导致循环在网络请求还没返回结果时就重复执行,瞬间发起大量请求,完全达不到“等待结果再决定是否继续”的目的。下面针对你的疑问给出具体解决方案:
疑问解答与实现方案
方案1:递归调用(兼容Swift 5.5之前版本)
把请求逻辑封装成独立函数,当条件不满足时,在请求回调里递归调用自身,模拟循环效果。
func fetchUntilConditionMet(completionHandler: @escaping (Result<[YourDataType], Error>) -> Void) { // 发起异步网络请求 request { response in switch response { case .success(let res): if res.count == 10 { // 满足条件,触发完成回调 completionHandler(.success(res)) } else { // 不满足条件,递归调用自身继续请求 // 可选:添加延迟避免请求过于频繁(比如延迟1秒) DispatchQueue.global().asyncAfter(deadline: .now() + 1) { fetchUntilConditionMet(completionHandler: completionHandler) } } case .failure(let error): // 请求失败,直接返回错误 completionHandler(.failure(error)) } } } // 调用示例 fetchUntilConditionMet { result in switch result { case .success(let data): print("满足条件,数据:\(data)") case .failure(let error): print("请求失败:\(error)") } }
方案2:Async/Await(Swift 5.5+,推荐)
利用Swift的异步语法,写出和你伪逻辑一致的代码,天然支持等待请求完成后再执行循环。
第一步:将回调式请求转为异步函数
// 把原有的回调式request包装成async函数 func requestAsync() async throws -> [YourDataType] { return try await withCheckedThrowingContinuation { continuation in request { response in switch response { case .success(let res): continuation.resume(returning: res) case .failure(let error): continuation.resume(throwing: error) } } } }
第二步:用while循环实现逻辑
func fetchUntilConditionMet() async throws -> [YourDataType] { while true { let res = try await requestAsync() if res.count == 10 { return res } // 可选:添加延迟避免频繁请求 try await Task.sleep(nanoseconds: 1_000_000_000) // 延迟1秒 } } // 调用示例 Task { do { let data = try await fetchUntilConditionMet() print("满足条件,数据:\(data)") } catch { print("请求失败:\(error)") } }
针对你的两个疑问的直接回答
- 条件未满足时如何继续循环?
- 递归方案:在请求成功但不满足条件的分支里,再次调用请求函数即可。
- Async/Await方案:无需额外操作,
while循环会在await拿到结果后自动进入下一次迭代。
- 如何让循环等待直至触发继续执行?
- 递归方案:利用异步回调的特性,只有当前请求完成并触发回调后,才会发起下一次请求,天然实现等待。
- Async/Await方案:通过
await关键字暂停循环,直到异步请求返回结果,再继续执行后续逻辑。
内容的提问来源于stack exchange,提问作者Chinmay Atrawalkar
相关产品推荐
相关产品推荐

