Waiting for request to finish before executing the next operation

Deadly 提交于 2019-12-24 02:13:41

问题


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()
}

回答1:


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.
})


来源:https://stackoverflow.com/questions/39899105/waiting-for-request-to-finish-before-executing-the-next-operation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!