如何让另一个异步调用等待?

Posted

技术标签:

【中文标题】如何让另一个异步调用等待?【英文标题】:How to make another async call wait? 【发布时间】:2020-11-10 08:21:52 【问题描述】:

如果其中一个异步调用在继续其他调用之前捕获到需要首先完成的条件,如何暂停另一个异步调用?从下面的代码(简化)来看,当 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,并且没有理由暂停其中任何一个,所以我对 @Goergisn 很贪心,您应该将请求堆栈/序列并一个接一个地运行您的请求并在需要时重新创建您的会话。对于并发请求,您可以在第一次失败时创建新会话,但您应该再次重新创建所有请求。 【参考方案1】:

如果在收到 401 时需要重试 API,可以尝试使用 Alamofire 的 RequestInterceptor 中的 RequestRetrier。它基本上会重试在您的情况下遇到错误(例如 401)的请求。

可以在here 找到完整的实现示例。希望对你有帮助,加油!

【讨论】:

以上是关于如何让另一个异步调用等待?的主要内容,如果未能解决你的问题,请参考以下文章

如何在.NET中调用异步函数而不等待它[重复]

如何等待来自 forEach 循环的多个异步调用?

如何在没有等待的情况下调用异步函数?

如何在单元测试之前等待组件的挂载回调中的异步调用完成?

在 iOS 中等待多个网络异步调用

如何等待来自 for 循环的多个异步调用?