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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift 4:创建一个异步串行队列,每个作业后等待2秒钟相关的知识,希望对你有一定的参考价值。

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

我想我需要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
}
答案

如果你有

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

那么,你的networkRetrieveFromQueue应该:

  • 检查队列是否为空;
  • 如果没有,抓住队列中的第一项;
  • 启动异步请求;和
  • 在该异步请求的完成处理程序中,在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是什么样的,但这说明了如何在某个异步方法的完成处理程序中递归调用函数的基本思想。

以上是关于Swift 4:创建一个异步串行队列,每个作业后等待2秒钟的主要内容,如果未能解决你的问题,请参考以下文章

GCD 异步串行队列 - 可以限制队列大小?

GCD使用 串行并行队列 与 同步异步执行的各种组合 及要点分析

IOS多线程知识总结/队列概念/GCD/串行/并行/同步/异步

iOS多线程知识总结/队列概念/GCD/串行/并行/同步/异步

swift/OC中的死锁问题

ios多线程同步异步、串行并行队列、死锁