Zba*_*itZ 1 completionhandler swift
也许我不理解完成处理程序的概念,但我有一个像这样的函数;
func someFunction(completion: @escaping (Bool, LoginError?) -> Void) {
self.checkDevice() { allowed, error in
if let e = error {
completion(false, e)
}
completion(true, nil)
}
}
Run Code Online (Sandbox Code Playgroud)
虽然不了解具体内容checkDevice(),但基本前提是它执行异步网络调用,并返回true且无错误 (nil),或者返回false(有错误)。
当我运行此代码时,我发现完成处理程序被调用两次。它将完成作为元组 (as false, error) 和 ( true, nil) 发送。我已经做了一些调试,似乎没有办法someFunction()调用两次。
我相信一旦发送完成,函数就会结束。在我的测试用例中,我强制从 中产生错误checkDevice(),这应该会导致我将完成发送为 ( false, error),但我同时看到 ( false, error) 和 ( true, nil)。完成不会立即结束函数吗?
\n\n\n我相信一旦发送完成,函数就会结束。
\n
不,为什么会这样?当您调用此函数时,它就像调用任何其他函数一样。这个名字没有魔力。
\n\n像这样重写它:
\n\nfunc someFunction(completion: @escaping (Bool, LoginError?) -> Void) {\n self.checkDevice() { allowed, error in\n if let e = error {\n completion(false, e)\n return // *\n }\n completion(true, nil)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n实际上,我应该指出,这是编写完成处理程序的糟糕方法。它不应该采用两个参数,一个 Bool 和一个仅在 Bool 为 时才使用的可选 LoginError false,而应该采用一个参数 \xe2\x80\x94 一个 Result,它携带我们是否成功或失败,以及如果我们失败了,什么错误是:
func someFunction(completion: @escaping (Result<Void, Error>) -> Void) {\n self.checkDevice() { allowed, error in\n completion( Result {\n if let e = error { throw e }\n })\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n正如您所看到的,使用结果作为参数可以让您更优雅地响应发生的情况。
\n\n事实上,checkDevice它本身可以将 Result 传递到其完成处理程序中,然后事情会更加优雅(也更简单)。
| 归档时间: |
|
| 查看次数: |
1042 次 |
| 最近记录: |