【问题标题】:parse nested completion handlers解析嵌套完成处理程序
【发布时间】:2017-08-30 02:48:02
【问题描述】:

我正在尝试在 for 循环中使用完成处理程序。问题是它会在完成处理程序返回之前继续运行循环,因为它是一个异步调用。附上我的代码。我需要使用 GCD 吗?我是 swift/ios 的新手(显然)。任何建议将不胜感激。鲍勃

    for srcTerm in sFields {  //search using all search fields

        multiQuery (searchTerm: srcTerm)   {

            if srResult.count < self.lastValue {
                self.lastValue = srResult.count
                self.lastSearch = srcTerm
            }
        }
        // Do more stuff
    }


    func multiQuery (searchTerm: String,  completion: @escaping ([PFObject]) -> ()) {

        var exArray = [PFObject] ()
        let query = PFQuery(className: "searchLinks")

        do {

            query.whereKey("searchTerms", equalTo: searchTerm)

            query.findObjectsInBackground  (block: { (objects, error)-> Void in
                if let error = error {
                    print("Error Generated:  ",error)
                    return
                }
                if let objects = objects {
                   // do stuff
                }
                completion(self.srResult)
            })
        }
    }               // end of function

【问题讨论】:

  • 有几种方法可以做到这一点(调度组、承诺等)。看看stackoverflow.com/a/23112134/2124535
  • 所有查询完成后你想做什么?上面链接的问题/响应(第二个)看起来就像您正在寻找的那样,尽管 API 在 Swift 3 中已经进行了一些更新。
  • 你能提供一个简单的例子来说明如何使用 GCD 做到这一点吗?非常感谢。

标签: swift asynchronous parse-platform completionhandler


【解决方案1】:

您可以使用 DispatchGroups,这是一个示例(取自 https://medium.com/@wilson.balderrama/how-to-use-dispatchgroup-gdc-with-swift-3-35455b9c27e7。类似于 GCD with nested Parse Queries,但已更新为 Swift 3 API):

// Just a sample function to simulate async calls
func run(after seconds: Int, closure: @escaping () -> Void) {
    let queue = DispatchQueue.global(qos: .background)
    queue.asyncAfter(deadline: .now() + .seconds(seconds)) {
        closure()
    }
}

let group = DispatchGroup()

group.enter()
run(after: 6) {
    print("Hello after 6 seconds")
    group.leave()
}

group.enter()
run(after: 3) {
    print("Hello after 3 seconds")
    group.leave()
}

group.enter()
run(after: 1) {
    print("Hello after 1 second")
    group.leave()
}


group.notify(queue: DispatchQueue.global(qos: .background)) {
    print("All async calls were run!")
}

使用您的代码:

let group = DispatchGroup()

for srcTerm in sFields {  //search using all search fields
    group.enter()
    multiQuery (searchTerm: srcTerm) {
        if srResult.count < self.lastValue {
            self.lastValue = srResult.count
            self.lastSearch = srcTerm
        }
        group.leave()
    }
}

group.notify(queue: DispatchQueue.global(qos: .background)) {
    // Do something after all async calls are done
}

【讨论】:

  • 谢谢内森!我没有意识到它那么简单。谢谢。
猜你喜欢
  • 1970-01-01
  • 2020-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-03
  • 2015-08-30
  • 1970-01-01
相关资源
最近更新 更多