等待两个完成处理程序?

时间:2018-07-10 09:50:33

标签: swift completionhandler

在我的应用程序内部,我对后端的请求很少。在一种情况下,我有一个应返回两个参数的函数(例如,可能是BoolBool)。但是我的问题来了。要返回这两个参数,我需要首先从后端接收一些信息,所以它看起来像这样(将用伪交换代码编写):

func request() -> (Bool, Bool) {
    var one: Bool?
    var two: Bool?

    Alamofire.request(url1).response { (response) in
        if let response = response { one = response }
    }

    Alamofire.request(url2).response { (response) in
        if let response = response { two = response }
    }

    if let one = one, let two = two {
        return (one, two)
    }

    return (nil, nil)
}

如何实现等待这两个Web请求的功能?

4 个答案:

答案 0 :(得分:1)

通常,遇到这种情况时,您将无法直接从函数返回值。我建议您应该采用对该方法进行回调的方法(使用@escaping闭包)。

另一方面,当两个请求都完成时,您需要执行回调。一种可能的解决方案是使用调度组(您可以检查:Call completion block when two other completion blocks have been called)。

对于将所有内容放在一起,您的功能应如下所示:

func request(callback: @escaping (_ one: Bool?,  _ two: Bool?) -> Void) {
    var one: Bool?
    var two: Bool?

    let group = DispatchGroup()

    group.enter()
    Alamofire.request(url1).response { (response) in
        if let response = response { one = response }
        group.leave()
    }

    group.enter()
    Alamofire.request(url2).response { (response) in
        if let response = response { two = response }
        group.leave()
    }

    group.notify(queue: DispatchQueue.main) {
        if let one = one, let two = two {
            callback(one, two)
        } else {
            callback(nil, nil)
        }
    }
}

因此,您将其称为:

request { (one, two) in
    // ...
}

答案 1 :(得分:1)

func request() -> (Bool?, Bool?) {
    var one: Bool?
    var two: Bool?
    let semaphore = DispatchSemaphore(value: 0)
    Alamofire.request(url1).response { (response) in
        if let response = response { one = response }
        semaphore.signal()
    }
    Alamofire.request(url2).response { (response) in
        if let response = response { two = response }
        semaphore.signal()
    }
    _ = semaphore.wait(timeout: DispatchTime.distantFuture)
    _ = semaphore.wait(timeout: DispatchTime.distantFuture)
    if let one = one, let two = two {
        return (one, two)
    }
    return (nil, nil)
}

答案 2 :(得分:0)

您可以尝试类似

var one: Bool?
var two: Bool?

func request() {

    Alamofire.request(url1).response { (response) in
        if let response = response { one = response }
        processResponse()
    }

    Alamofire.request(url2).response { (response) in
        if let response = response { two = response }
        processResponse()
    }
}

func processResponse() {
    if let one = one, let two = two {
        // do something
    }
}

答案 3 :(得分:0)

尝试以下方法:

func request(completion: ((Bool?, Bool?) -> Void)?) {
    var one: Bool?
    var two: Bool?

    Alamofire.request(url1).response { (response) in
        if let response = response { one = response }
        Alamofire.request(url2).response { (response) in
             if let response = response { two = response }

             completion?(one, two)
        }
   }
}