【问题标题】:Serial queue API multiple services calls串行队列 API 多个服务调用
【发布时间】:2018-08-01 07:31:47
【问题描述】:

如何在 swift 4 中通过串行队列进行多个 Web 服务调用(即在第一次调用完成后开始第二次调用)

 func allConcurretExce(completion: @escaping () -> ()) {
    let queue = DispatchQueue(label: "reverseDomain", attributes: .concurrent)
    let group = DispatchGroup()


    queue.async (group: group) {

        print("first call")

      self.userSignIn()


    }


    queue.async (group: group) {
        //group.wait(timeout : .now() + .seconds(3))
        print("second call")
        self.getMeData(token: self.token)


    }

    group.notify(queue: DispatchQueue.main) {
        completion()
    }
}

这就是我在第一次通话完成时正在做的事情,我得到了令牌并将该令牌发送给另一个通话。但我现在实现的是同时获得两个通话,这导致我的第二次通话出错。我的目标是从第一个获取令牌并发送到第二个而不使用处理程序。我想通过队列来实现。

【问题讨论】:

  • 所有 API 调用本质上都是异步的,所以即使您使用序列化队列,只要您进行 Web 服务调用,线程就会进行异步调用并进行第二次 Web 服务调用。这意味着尽管您在进行 Web 服务调用时实现了序列化,但您无法通过使用普通的串行队列/操作队列来实现 Web 服务调用完成的序列化。我通过使用异步操作和使用 operationQueue 并通过使其有效的序列化队列将最大并发操作设置为 1 实现了同样的事情:)
  • 其他替代方案是使用 Promise 工具包或使用块在第一个 Web 服务调用结束后触发下一个 Web 服务调用。但是,如果您正在考虑创建一个强制 web 服务调用串行执行的通用框架,那么您不能使用承诺或块(与逻辑耦合太紧密),使用 Operations 和 OperationQueue 将允许您编写通用框架。 Lemme 发布我正在谈论的 OperationQueue 修改的链接。
  • stackoverflow.com/questions/39201284/…。链接展示了如何覆盖操作的各种 KVO 属性以使其异步,并使用 OperationQueue 通过异步 Web 服务调用实现真正的序列化。虽然问题谈论的复杂性与您的问题无关,但应该给您一个良好的开端
  • 我已经编辑了我的问题。
  • 如果您只关心这两种方法,您不需要调度组或任何东西,只需先调用 userSignIn(),然后在 userSignIn 的最后一条语句中(显然在处理后的 API 完成块中) response ) userSignIn()完成后调用self.getMeData启动getMetaData

标签: ios swift queue


【解决方案1】:

您可以在 swift 中使用DispatchSemaphore 实现此目的。这将阻塞你的线程,直到一个任务结束,然后你可以开始另一个任务。检查下面的示例。

class HttpClassForGetData: NSObject {

    var result: Any? = nil
    var sem = DispatchSemaphore(value: 0) // create semaphore

    init() {

        // create post request
        let url = URL("example.com")!

        var request = URLRequest(url: url)
        request.httpMethod = "GET"

        let session = URLSession(configuration: URLSessionConfiguration.default, delegate:nil, delegateQueue:OperationQueue.main)
        var DATA = session.uploadTask(withStreamedRequest: request) // use uploadTask with completion handler API here.and in your API call completion block call self.sem.signal() method.
        result = DATA

        // continue work in anybodyclass.swift class
        _ = sem.wait(timeout: .distantFuture) // lock calling thread, put this code at the end
    }

}

并在您的 API 调用完成块中调用 self.sem.signal() 方法。有任何疑问欢迎评论。

【讨论】:

  • 我有 API,我想一一调用。
  • 好吧,在第一个 API 完成回调中启动下一个 API
猜你喜欢
  • 1970-01-01
  • 2017-09-07
  • 1970-01-01
  • 1970-01-01
  • 2019-07-22
  • 1970-01-01
  • 2017-10-16
  • 2018-06-25
  • 2014-09-15
相关资源
最近更新 更多