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

Swift并发async/await下如何替代带重试的成功回调模式?

解决方案:封装带重试逻辑的异步请求函数

核心思路是把「请求+失败重试弹窗」的逻辑封装成独立异步函数,调用方无需关心重试细节,只需await函数拿到最终成功结果即可。

实现步骤

1. 封装基础单次请求函数

先实现只负责单次网络请求的抛出型异步函数:

func fetchDataOnce() async throws -> Data {
    let url = URL(string: "https://your-api-url.com/data")!
    let (data, response) = try await URLSession.shared.data(from: url)
    
    guard let httpResponse = response as? HTTPURLResponse, 
          httpResponse.statusCode == 200 else {
        throw NetworkError.invalidResponse
    }
    return data
}

enum NetworkError: Error {
    case invalidResponse
    case requestFailed(Error)
}

2. 封装带重试交互的请求函数

将请求失败后的弹窗重试逻辑整合进异步循环,通过withCheckedContinuation将UI弹窗的回调转为异步等待:

func fetchDataWithRetry() async throws -> Data {
    while true {
        do {
            return try await fetchDataOnce()
        } catch {
            let shouldRetry = await showRetryAlert()
            if !shouldRetry {
                throw error // 用户取消重试,抛出原错误
            }
            // 用户选择重试,继续循环发起请求
        }
    }
}

// 异步弹窗函数,返回用户是否选择重试
func showRetryAlert() async -> Bool {
    return await withCheckedContinuation { continuation in
        let alert = UIAlertController(title: "请求失败", message: "是否重试?", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "重试", style: .default) { _ in
            continuation.resume(returning: true)
        })
        alert.addAction(UIAlertAction(title: "取消", style: .cancel) { _ in
            continuation.resume(returning: false)
        })
        
        // 获取当前顶层视图控制器(iOS 13+适配写法)
        if let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
           let rootVC = scene.windows.first?.rootViewController {
            rootVC.present(alert, animated: true)
        }
    }
}

3. 简洁的调用方式

调用方只需await封装后的函数,成功后执行后续操作,失败则处理用户取消的情况:

Task {
    do {
        let data = try await fetchDataWithRetry()
        // 请求成功,执行原回调逻辑(比如显示搜索框)
        showSearchBar()
    } catch {
        print("用户取消请求:\(error)")
        // 处理用户取消后的逻辑
    }
}

方案优势

  • 完全基于async/await实现,彻底消除传统完成回调,符合迁移初衷。
  • 循环+异步等待的逻辑保证:首次失败后,用户点击重试会重新发起请求,直到成功或用户取消,最终成功时能正常触发后续操作。
  • 请求逻辑与UI交互逻辑解耦,代码结构更清晰,便于维护和扩展。

注意事项

  • 可根据错误类型调整重试策略,比如仅对网络超时、服务器错误等可重试错误弹窗,在catch分支中判断错误类型即可。
  • 顶层视图控制器的获取方式需根据项目的UI架构调整,确保弹窗能正确显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 12:03:16