代码之家  ›  专栏  ›  技术社区  ›  ANoobSwiftly

Swift 4:创建异步串行队列,每个作业后等待2秒

  •  1
  • ANoobSwiftly  · 技术社区  · 7 年前

    无法想象这一点。。。

    我想我需要2个线程,但不确定如何实现它们。

    完成后,我需要在每个网络检索请求之间至少有2秒的延迟。

    主螺纹:

    ui按钮已按下-->函数将网络检索请求添加到串行队列-->UILoop继续。。。

    网络线程:

    检查队列中的下一个请求-->开始请求-->完成请求-->等待2秒-->检查队列中的下一个请求-->开始请求-->完成请求-->等待2秒-->检查队列中的下一个请求-->无请求-->检查队列中的下一个请求。。。或结束循环,直到调用为止。

    var networkQueue = [NetworkRequest]()
    var networkQueueActive = false
    
    @IBAction func buttonPressed(_ sender: UIButton) {
        networkQueue.append(NetworkRequest(UIButton))
        if networkQueueActive == false {
            networkRetrieveFromQueue() // need to asynchronously call this DON'T KNOW HOW TO DO THIS
        }
    }
    
    func networkRetrieveFromQueue() {
        networkQueueActive = true
        while !networkQueue.isEmpty {
            let request = networkQueue.remove(at: 0)
            // synchronous network data retrieval on this thread KNOW HOW TO DO THIS
            // do something with the data retrieved KNOW HOW TO DO THIS
            // wait 2 seconds DON'T KNOW HOW TO DO THIS
        }
        networkQueueActive = false
    }
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   Rob Md Fahim Faez Abir    7 年前

    如果你有

    var networkQueue = [NetworkRequest]()
    var networkQueueActive = false
    

    那么,你的 networkRetrieveFromQueue 应:

    • 检查队列是否为空;
    • 如果没有,抓取队列中的第一个项目;
    • 发起异步请求;和
    • 在该异步请求的完成处理程序中,调用 networkRetrieveFromQueue 2秒后再次

    因此

    func startQueue() {
        if networkQueueActive { return }
    
        networkQueueActive = true
        processNext()
    }
    
    // if queue not empty, grab first item, perform request, and call itself
    // 2 seconds after prior one finishes
    
    func processNext() {
        if networkQueue.isEmpty {
            networkQueueActive = false
            return
        }
    
        let request = networkQueue.removeFirst()
    
        get(request: request) {
            DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                self.processNext()
            }
        }
    }
    

    您的“流程请求”可能如下所示:

    // perform asynchronous network request, with completion handler that is 
    // called when its done
    
    func get(request: NetworkRequest, completionHandler: @escaping () -> Void) {
        let task = URLSession.shared.dataTask(with: request.request) { data, _, error in
            guard let data = data, error == nil else {
                print(error ?? "Unknown error")
                completionHandler()
                return
            }
    
            // process successful response here
    
            // when done, call completion handler
    
            completionHandler()
        }
        task.resume()
    }
    

    现在,我不知道你的 NetworkRequest 看起来像,但这说明了如何在某个异步方法的完成处理程序中递归调用函数的基本思想。