Swift 3.0 中的完成处理程序 [英] Completion handlers in Swift 3.0

查看:16
本文介绍了Swift 3.0 中的完成处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用下面的代码与我的服务器同步数据.完成任务后,我想打电话:

I am using the code below to sync data with my server. After completing the task, I would like to call:

self.refreshControl?.endRefreshing()

但是,我想确保它发生在此方法中可能发生的任何事情之后.这是我将使用完成处理程序的地方吗?这让我感到困惑,因为我已经在运行在获得 http 响应后执行的代码.如果我添加一个完成处理程序,它会在收到 http 响应后执行吗?我可以把我的 endRefreshing() 代码放在那里,在下面的代码中可能发生的任何事情之后发生吗?谢谢!

However, I would like to make sure it happens after anything that might happen inside this method. Is this where I would use a completion handler? It is confusing to me because I am already running code that gets executed after getting the http response. If I add a completion handler, does it get executed after the http response is received? And could I put my endRefreshing() code there that would happen after anything that might happen in the code below? Thanks!

func syncCustomers(token: String) {
    let url:NSURL = NSURL(string: Constants.Api.BaseUrl + "api/customer")!
    let session = URLSession.shared
    let request = NSMutableURLRequest(url: url as URL)
    request.setValue("Bearer (token)", forHTTPHeaderField: "Authorization")
    request.httpMethod = "GET"
    let task = session.dataTask(with: request as URLRequest) { (data, response, error) in
        guard let data = data else { return }
        do {
            if error != nil {
                self.showAlert(title: "Error", message: error!.localizedDescription)
            }
            else if let httpResponse = response as? HTTPURLResponse {
                if httpResponse.statusCode == 200 {
                    let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? Array<Any>
                    DispatchQueue.global().async {
                        for item in json! {
                            if let customer = Customer(json: item as! [String : Any]) {
                                _ = SqliteDB.instance.replaceCustomer(customer: customer)
                            }
                        }
                        self.customers = SqliteDB.instance.getCustomers()
                        self.tableView.reloadData()
                    }
                } else if httpResponse.statusCode == 401 {
                    self.showAlert(title: "Error", message: "Unauthorized. Please try logging in again.")

                }
            }
        } catch let error as NSError {
            self.showAlert(title: "Error", message: error.localizedDescription)
        }
    }
    task.resume()
}

推荐答案

完成或闭包只是一个封装在参数中的函数...

A completion or closure is just a function wrapped up into a parameter...

你可以像这样创建一个带有闭包的函数......

You can create a function with a closure like so...

func doSomethingAsync(completion: () -> ()) {
}

参数 completion 的类型是 () ->() 即...它是一个函数 -> 不接受输入参数 () 并返回 void ()>.

The parameter completion is of type () -> () that is... it is a function -> that takes no input parameters () and returns void ().

你也可以做一个像...这样的函数

You could also make a function like...

// (inputs) -> (outputs)
(String) -> ()

或者使用您想要的任何输入或输出.

Or with any inputs or outputs you want.

现在,就像您在问题中所说的那样.这个函数可能会调用一些其他的异步函数...

Now, like you have in your question. This function may call some other async function...

func myAsyncFunction(completion: () -> ()) {

    someOtherAsyncFunction() {

        // This is the completion of "someOtherAsyncFunction"

        // Call YOUR completion here...
        completion()
    }

}

要确保在其他异步方法完成后调用您的完成,请将其放在其他方法的完成中.如上.

To make sure that YOUR completion is called AFTER the other async method is done put it inside the completion of the other method. Like above.

现在,你可以调用这个...

Now, to call this you can do...

self.myAsyncFunction() {
    // your completion block code here.
}

现在将在其他异步方法完成后调用您的完成块代码.

Your completion block code will now be called AFTER the other async method has finished.

当然,如果您在另一个完成中有多个路径(例如错误等...),那么您必须在每个端点调用您的完成...

Of course, if you have several paths in the other completion (like errors etc...) then you have to call your completion at each end point...

func myAsyncFunction(completion: () -> ()) {

    someOtherAsyncFunctionWithAPossibleError() {
        error in

        if error != nil {
            completion()
            // this return means the other completion won't be run
            return
        }

        completion()
    }

}

这篇关于Swift 3.0 中的完成处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆