简体   繁体   中英

Waiting for request to finish before executing the next operation

I'm wanting to know how to wait for an operation that is sending a request to finish uploading (and get response) before executing another bit of code. I've attempted to do this with NSOperations:

    let testOp = BlockOperation {
        var result = 0

        for i in 1...1000000000 {
            result += i
        }
    }

    let logOp = BlockOperation {
        self.debug.log(tag: "test", content: "testing")
    }

    logOp.completionBlock = {
        print("------- logOp completed")
    }

    logOp.addDependency(testOp)

    let sendOp = BlockOperation {
        self.debug.sendLog() //uploads log, using URLSession.shared.dataTask
    }

    sendOp.completionBlock = {
        print("------- sendOp completed")
    }

    sendOp.addDependency(logOp)

    let emptyOp = BlockOperation {
        self.debug.empty()
    }

    emptyOp.completionBlock = {
        print("------- emptyOp completed")
    }

    emptyOp.addDependency(sendOp)

    let queue = OperationQueue()
    queue.addOperations([testOp, logOp, sendOp, emptyOp], waitUntilFinished: false)

Output:

------- logOp completed
*** Sending debug log (coming from self.debug.sendLog())
------- sendOp completed
------- emptyOp completed
*** sendLog uploaded (coming from self.debug.sendLog())

Based on my code I expected the output to be:

------- logOp completed
*** Sending debug log
*** sendLog uploaded
------- sendOp completed
------- emptyOp completed

How do I make it so? Can I do this with NSOperations?

Additional detail about the debug.sendLog() function:

func sendLog() {
    ...
    var urlRequest = URLRequest(url: url!)
    urlRequest.httpMethod = "POST"
    ...

    let session = URLSession.shared
    let task = session.dataTask(with: urlRequest, completionHandler: {
        (data, response, error) in

        ...

        DispatchQueue.main.async {
            print("*** sendLog uploaded")

        }
    })

    task.resume()
}

You could add the completion block straight to the sendLog method and ditch all the block operation stuff.

func sendLog(withCompletion completion: (() -> Void)) {
    ...
    var urlRequest = URLRequest(url: url!)
    urlRequest.httpMethod = "POST"
    ...

    let session = URLSession.shared
    let task = session.dataTask(with: urlRequest, completionHandler: {
        (data, response, error) in

        ...
        completion?()
    })

    task.resume()
}

Then call your sendLog method like this:

sendLog(withCompletion: {
   // Execute the code you want to happen on completion here.
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM