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

Swift中多个异步请求等待同一任务完成的正确实现方式

异步请求中确保Token刷新仅执行一次的正确实现方式

我有一个处理应用所有网络请求的通用异步request方法,逻辑是先检查access token是否有效,若已过期则调用accessTokenRefreshableService刷新token。但这个刷新服务只能被调用一次,因为它用的refreshToken是单次有效的。

我原本想用信号量semaphore.wait()和semaphore.signal()来保证刷新服务仅执行一次,且所有请求都等待刷新完成,但这不是正确方案,还出现了警告:

Instance method 'wait' is unavailable from asynchronous contexts; Await a Task handle instead; this is an error in Swift 6

原代码如下:

func request<T: Decodable, S: APIServiceProtocol>(service: S) async throws -> T {
    // Access token
    semaphore.wait()
    if let accessToken = service.accessToken {
        if JWT.isTokenExpired(accessToken) {
            try await accessTokenRefreshableService.request()
        }
    }
    semaphore.signal()
    
    // Prepare request
    // Make request
    // Handle result
}

在Swift异步并发环境中,不能用传统信号量阻塞线程,正确做法是用共享的Task实例控制刷新操作,确保同一时间只有一个刷新任务执行,所有等待的请求复用该任务的结果。

具体实现

  1. 在网络请求管理类中添加可选Task属性,跟踪当前刷新任务:
private var refreshTask: Task<Void, Error>?
  1. 修改request方法的token刷新逻辑:
func request<T: Decodable, S: APIServiceProtocol>(service: S) async throws -> T {
    // 检查并处理token过期
    if let accessToken = service.accessToken, JWT.isTokenExpired(accessToken) {
        if let task = refreshTask {
            // 已有刷新任务,等待其完成
            try await task.value
        } else {
            // 创建新的刷新任务
            let task = Task {
                try await accessTokenRefreshableService.request()
            }
            refreshTask = task
            do {
                try await task.value
            } catch {
                // 刷新失败,清空任务允许后续重试
                refreshTask = nil
                throw error
            }
            // 刷新成功,清空任务
            refreshTask = nil
        }
    }
    
    // Prepare request
    // Make request
    // Handle result
}

关键说明

  • 用refreshTask记录当前是否有刷新任务在执行,避免多请求重复触发刷新
  • 所有需等待刷新的请求都会await同一个Task结果,符合Swift异步非阻塞特性
  • 刷新完成(成功/失败)后清空refreshTask,确保下次token过期时能重新发起刷新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:22:11