首页 文章

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

提问于
浏览
1

无法想象这个......

我想我需要2个线程,我不知道如何实现它们 .

我需要在每个网络检索请求完成后最少延迟2秒 .

主线程:

按下UIButton - > Function将网络检索请求添加到串行队列 - > 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 回答

  • 1

    如果你有

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

    然后,你的 networkRetrieveFromQueue 应该:

    • 检查队列是否为空;

    • 如果没有, grab 队列中的第一项;

    • 启动异步请求;和

    • 在该异步请求的完成处理程序中,2秒后再次调用 networkRetrieveFromQueue

    从而

    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 是什么样的,但这说明了如何在某个异步方法的完成处理程序中递归调用函数的基本思想 .

相关问题