9

让我们提出这个方案

具有异步网络操作的方法

func asyncMethodA() -> String?
{
   result : String?
   Alamofire.manager.request(.POST, "https://www.apiweb.com/apimethod", parameters: parameters, encoding:.JSON)
            .response { (request, response, rawdata, error) in
                if (response?.statusCode == 200)
                {
                    //DO SOME HEAVY LIFTING
                }
        }
        return result //string

}

另一种具有异步网络操作的方法

func asyncMethodB() -> String?
{
   result : String?
   Alamofire.manager.request(.POST, "https://www.yetanotherapiweb.com/apimethod", parameters: parameters, encoding:.JSON)
            .response { (request, response, rawdata, error) in
                if (response?.statusCode == 200)
                {
                    //DO SOME HEAVY LIFTING

                }
        }
        return result //string
}

我将在其中调用这些方法 A 和 B 来执行某些操作的方法

func displayResult
{
   1)  let a = asyncMethodA()
   2)  let b = asyncMethodB()
   3)  println(a + b) //some chaotic stuff might happen :(
}

所以问题是我怎样才能让(2)等待(1)运行,(3)等待(2)等等(1,2和3运行同步)?

(我知道一个答案是将 asyncMethodA 和 displayResult 链接到 asyncMethodB,但想知道是否有其他方法)

谢谢你!。

4

3 回答 3

18
func anAsyncMethod(resultHandler: (result: AnyObject) -> Void) {
    ...        
}

func anotherAsyncMethod(resultHandler: (result: AnyObject) -> Void) {
    ... 
}

let operationQueue = NSOperationQueue()

func performWithCompletionHandler(completion: (AnyObject?, AnyObject?) -> Void) {
        var resultOfOperation1: AnyObject?
        var resultOfOperation2: AnyObject?

        let operation1 = NSBlockOperation {
                let dispatchGroup = dispatch_group_create()
                dispatch_group_enter(dispatchGroup)
                self.anAsyncMethod {
                        result in
                        resultOfOperation1 = result
                        dispatch_group_leave(dispatchGroup)
                }
                // wait until anAsyncMethod is completed
                dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER)
        }

        let operation2 = NSBlockOperation {
                let dispatchGroup = dispatch_group_create()
                dispatch_group_enter(dispatchGroup)
                self.anotherAsyncMethod {
                        result in
                        resultOfOperation2 = result
                        dispatch_group_leave(dispatchGroup)
                }
                // wait until anotherAsyncMethod is completed
                dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER)
        }

        let completionOperation = NSBlockOperation {
                // send all results to completion callback
                completion(resultOfOperation1, resultOfOperation2)
        }

        // configuring interoperation dependencies
        operation2.addDependency(operation1)
        completionOperation.addDependency(operation2)

        operationQueue.addOperations([operation1, operation2, completionOperation], waitUntilFinished: false)
}
于 2014-11-28T02:51:50.197 回答
5

感谢 Yimin 提供上面的代码。我已经将它更新为最新的 Swift 语法,所以只是发布以提供帮助:

func anAsyncMethod(resultHandler: (_ result: AnyObject) -> Void) {
    ...
}

func anotherAsyncMethod(resultHandler: (_ result: AnyObject) -> Void) {
    ...
}

func performWithCompletionHandler(completion: @escaping (AnyObject?, AnyObject?) -> Void) {

    let operationQueue = OperationQueue()

    var resultOfOperation1: AnyObject?
    var resultOfOperation2: AnyObject?

    let operation1 = BlockOperation {
        let dispatchGroup = DispatchGroup()
        dispatchGroup.enter()
        self.anAsyncMethod {
            result in
            resultOfOperation1 = result
            dispatchGroup.leave()
        }
        // wait until anAsyncMethod is completed
        dispatchGroup.wait(timeout: DispatchTime.distantFuture)
    }

    let operation2 = BlockOperation {
        let dispatchGroup = DispatchGroup()
        dispatchGroup.enter()
        self.anotherAsyncMethod {
            result in
            resultOfOperation2 = result
            dispatchGroup.leave()
        }
        // wait until anotherAsyncMethod is completed
        dispatchGroup.wait(timeout: DispatchTime.distantFuture)
    }

    let completionOperation = BlockOperation {
        // send all results to completion callback
        completion(resultOfOperation1, resultOfOperation2)
    }

    // configuring interoperation dependencies
    operation2.addDependency(operation1)
    completionOperation.addDependency(operation2)

    operationQueue.addOperations([operation1, operation2, completionOperation], waitUntilFinished: false)
}
于 2018-02-16T22:58:36.950 回答
1

使用以下内容,您可以同时启动两种异步方法,并在最后一个完成之后进行繁重的工作。

var methodAFinished = false
var methodBFinished = false

func asyncMethodA() -> String?
{
    Alamofire.manager.request(.POST, "https://www.apiweb.com/apimethod", parameters: parameters, encoding:.JSON)
        .response { (request, response, rawdata, error) in
            if (response?.statusCode == 200) {
                methodAFinished = true
                doStuff()
            }
        }
    return result //string
}

asyncMethodB 的核心是methodBFinished = true; doStuff()

func doStuff() {
    if methodAFinished && methodBFinished {
        // do crazy stuff
    }
}
于 2014-11-27T19:05:47.273 回答