如果其中一个调用在继续其他调用之前需要先完成的条件,如何暂停另一个异步调用?从下面的代码(简化)来看,当makeRequest得到401时,它应该调用refreshSession并暂停其他调用,直到这个调用完成。
let refreshSessionDispatchQueue = DispatchQueue(label: "refreshSession")
var refreshSessionJobQueue: [APIRequest] = []
// This function will be called by each of APIs that got 401 error code
private func refreshSession(errorCode: String? = nil, request: APIRequest) {
refreshSessionDispatchQueue.async {
self.refreshSessionJobQueue.append(request)
}
// The idea is, after all job appended to the jobQueue, let says after 1', it will call another function to execute another job
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
self.executeRefreshSessionJobQueue()
}
}
// This is to execute refreshSession, and if it's succeed, all job on the jobQueue will be re-executed
private func executeRefreshSessionJobQueue() {
DispatchQueue.main.async {
let readyToRefreshSessionJobQueue = self.refreshSessionJobQueue
if self.refreshSessionJobQueue.count > 0 {
self.refreshSessionJobQueue = []
self.refreshSession { [weak self] succeed in
if succeed {
for job in readyToRefreshSessionJobQueue {
self?.makeRequest(baseURL: job.baseURL, endpoint: job.endpoint, method: job.method, encoding: job.encoding, headers: job.headers, params: job.params, customBody: job.customBody, completion: job.completion)
}
self?.refreshSessionJobQueue = []
} else {
// And if it's failed, all the job should be removed and redirect the page to the login page
self?.refreshSessionJobQueue = []
ErrorHandler.relogin()
}
}
}
}
}
如果在获取 401 时需要重试 API,可以尝试使用 Alamofire 的 RequestInterceptor 中的 RequestRetrier。在您的情况下,它基本上会重试遇到错误(例如 401)的请求。
完整的实现示例可以在这里找到。希望能帮到你,加油!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句