我不希望这被误解为副本。我想处理来自Firestore的API调用(Firebase,Google平台的数据库)引起的回调地狱。我不能修改它们的函数声明,所以我假设我必须用我的一些代码包装它们的函数。
例如,在下面的代码中,函数eventCreatedSuccessfully()
只能在异步函数完成后调用。 eventCreatedSuccessfully()
还包含对firebase的函数调用,该函数调用有一个闭包,另一个函数依赖于等等......虽然现在这不会给我带来问题,但它可能随着我的App越来越大而变得越来越大。我在网上研究并从第三方框架中找到了Futures和Streams等解决方案,但我不知道如何将它们集成到我无法控制的代码中(API调用)。
batch.commit { (error) in
self.dismiss(animated: true) {
if error == nil {
self.eventCreatedSuccessfully()
print("Event created successfully")
} else {
print(error!.localizedDescription)
}
}
}
答案 0 :(得分:1)
将电话包裹在承诺中。任何流行的图书馆都可以解决问题。想到的是PromiseKit(在撰写本文时)https://github.com/mxcl/PromiseKit可用。
这是我为工作项目(它的开源)编写的代码,它包含一个完成的函数,并返回一个Promise,它将在调用完成时通知结果。它使用内部Promise实现,但该过程可以适应其他实现。
public func promise<Return>(_ task: (@escaping (Return?, Error?) -> ()) -> ()) -> Promise<Return> {
let p = Promise<Return>()
task { (value: Return?, error: Error?) -> Void in
if let error = error {
p.signal(error)
}
if let value = value {
p.signal(value)
}
}
return p
}
预计会因某种结果或错误而调用完成。根据您的用例进行调整。
以下是一个示例用法。
public typealias BalanceCompletion = (Balance?, Error?) -> Void
func balance(completion: @escaping BalanceCompletion) {
guard deleted == false else {
completion(nil, KinError.accountDeleted)
return
}
Stellar.balance(account: stellarAccount.publicKey!, asset: asset, node: node)
.then { balance -> Void in
completion(balance, nil)
}
.error { error in
completion(nil, KinError.balanceQueryFailed(error))
}
}
func balance() -> Promise<Balance> {
return promise(balance)
}
答案 1 :(得分:0)
我在网上研究并找到了Futures和Streams(...)
等解决方案
在大多数情况下,期货和流都是PromiseKit
和RxSwift
框架。
如果您只有大量关闭,请尝试使用PMK。它非常简单易用。 PMK在github上也有很好的documentation section。
RxSwift是更高级的,因为它要求你完全编写代码到自己的范例 - 从server / firebase请求开始,以ui结束。此外,PMK github还有good note关于这两者的差异。
另外,应该注意的是,Google也有一个很好的名为promises
的库。根据他们的benchmarks谷歌图书馆几乎所有提名都是领导者。