如何在闭包中使用 DispatchSemaphore
How can I use DispatchSemaphore with a Closure
我有一个看起来像这样的值
lazy var authHeaders: [String: String] = {
if shouldTokenBeRefreshed() {
let semaphore = DispatchSemaphore(value: 0)
refreshTokens {
semaphore.signal()
}
semaphore.wait()
}
return ["Authorization": "Bearer \(module.client.credential.oauthToken)"]
}()
想法是,当请求我的 auth headers
时,如果我的令牌已过期,我将刷新它,然后 return 新值。
func refreshTokens(completion: @escaping () -> Void) {
guard let token = keychain.get("refresh_token") else { return }
module.renewAccessToken(
withRefreshToken: token,
success: { [weak self] credential, response, parameters in
guard let self = self else { return }
self.storeTokens([
"access_token": credential.oauthToken,
"refresh_token": credential.oauthRefreshToken
])
completion()
},
failure: { error in
print(error.description)
})
}
由于这是一个 async
操作,我尝试使用 Semaphore
暂停流程,以便在触发完成块后使其继续。
但是通话没有解决,我不确定为什么。
我不太清楚你的意思
The call is not resolving
但是在您的示例中有几点需要注意。
- 确保 authHeaders 没有在主线程上初始化,因为信号量会阻塞您的 UI。
- 信号量停止等待的唯一方式是执行完成闭包。您的代码中有多种路径不会执行完成闭包。在
refreshTokens
中,第一个 guard
失败或遇到失败块不会执行完成关闭,因此信号量不会停止等待。
这不是您应该使用的方式 DispatchSemaphore
。
请不要强制异步代码同步。
您将需要重构代码以更好地处理您要实现的目标的异步性质。
完成处理程序是更简单、更有效的方法。如果您出于某种原因试图避免这种情况,请查看 PromiseKit 或其他异步帮助程序库。
另一个建议是不要在飞行前更新您的令牌,而是在 401 上更新它们,然后重放您原始的更新请求。
我有一个看起来像这样的值
lazy var authHeaders: [String: String] = {
if shouldTokenBeRefreshed() {
let semaphore = DispatchSemaphore(value: 0)
refreshTokens {
semaphore.signal()
}
semaphore.wait()
}
return ["Authorization": "Bearer \(module.client.credential.oauthToken)"]
}()
想法是,当请求我的 auth headers
时,如果我的令牌已过期,我将刷新它,然后 return 新值。
func refreshTokens(completion: @escaping () -> Void) {
guard let token = keychain.get("refresh_token") else { return }
module.renewAccessToken(
withRefreshToken: token,
success: { [weak self] credential, response, parameters in
guard let self = self else { return }
self.storeTokens([
"access_token": credential.oauthToken,
"refresh_token": credential.oauthRefreshToken
])
completion()
},
failure: { error in
print(error.description)
})
}
由于这是一个 async
操作,我尝试使用 Semaphore
暂停流程,以便在触发完成块后使其继续。
但是通话没有解决,我不确定为什么。
我不太清楚你的意思
The call is not resolving
但是在您的示例中有几点需要注意。
- 确保 authHeaders 没有在主线程上初始化,因为信号量会阻塞您的 UI。
- 信号量停止等待的唯一方式是执行完成闭包。您的代码中有多种路径不会执行完成闭包。在
refreshTokens
中,第一个guard
失败或遇到失败块不会执行完成关闭,因此信号量不会停止等待。
这不是您应该使用的方式 DispatchSemaphore
。
请不要强制异步代码同步。
您将需要重构代码以更好地处理您要实现的目标的异步性质。
完成处理程序是更简单、更有效的方法。如果您出于某种原因试图避免这种情况,请查看 PromiseKit 或其他异步帮助程序库。
另一个建议是不要在飞行前更新您的令牌,而是在 401 上更新它们,然后重放您原始的更新请求。