swift - 在 Swift 中链接 Promise 以初始化自定义对象
问题描述
我PromiseKit
在 Swift 中实现以避免带有完成块的回调地狱。我需要知道将 Promise 链接在一起以初始化具有其他关联对象的自定义对象的最佳方法。例如Comment
,一个User
对象附加了一个对象。
首先,我comments
从数据库中获取,它们在数据库结构中都有一个uid
属性。我最终希望得到一个 数组comments
,每个数组都附加了正确的用户,所以我可以同时加载comment
和user
数据。使用完成块,这一切似乎都容易得多,但我完全是个Promise
菜鸟,所以我很不喜欢。
这是控制器中处理获取的代码
CommentsService.shared.fetchComments(withPostKey: postKey)
.then { comments -> Promise<[User]> in
let uids = comments.map({ $0.uid })
return UserService.shared.fetchUsers(withUids: uids)
}.done({ users in
// how to init Comment object with users now?
})
.catch { error in
print("DEBUG: Failed with error \(error)")
}
这是评论获取功能:
func fetchComments(withPostKey postKey: String) -> Promise<[Comment]> {
return Promise { resolver in
REF_COMMENTS.child(postKey).observeSingleEvent(of: .value) { snapshot in
guard let dictionary = snapshot.value as? [String: AnyObject] else { return }
let data = Array(dictionary.values)
do {
let comments = try FirebaseDecoder().decode([Comment].self, from: data)
resolver.fulfill(comments)
} catch let error {
resolver.reject(error)
}
}
}
}
这是获取用户功能
func fetchUsers(withUids uids: [String]) -> Promise<[User]> {
var users = [User]()
return Promise { resolver in
uids.forEach { uid in
self.fetchUser(withUid: uid).done { user in
users.append(user)
guard users.count == uids.count else { return }
resolver.fulfill(users)
}.catch { error in
resolver.reject(error)
}
}
}
}
这是评论对象:
struct Comment: Decodable {
let uid: String
let commentText: String
let creationDate: Date
var user: User?
}
完成块就是这么简单,开始认为 Promise 不值得?
func fetchComments(withPostKey postKey: String, completion: @escaping([Comment]) -> Void) {
var comments = [Comment]()
REF_COMMENTS.child(postKey).observe(.childAdded) { (snapshot) in
guard let dictionary = snapshot.value as? [String: AnyObject] else { return }
guard let uid = dictionary["uid"] as? String else { return }
UserService.shared.fetchUser(withUid: uid, completion: { (user) in
let comment = Comment(user: user, dictionary: dictionary)
comments.append(comment)
completion(comments)
})
}
}
解决方案
好的,我想我明白您要做什么。问题是您需要与用户一起捕获评论,以便您可以一起返回然后将它们组合起来。它应该看起来像这样:
CommentsService.shared.fetchComments(withPostKey: postKey)
.then { comments -> Promise<[Comment], [User]> in
let uids = comments.map({ $0.uid })
return UserService.shared.fetchUsers(withUids: uids)
.then { users in
return Promise<[Comment], [User]>(comments, users)
}
}.done({ combined in
let (comments, users) = combined
//Do combiney stuff here
})
.catch { error in
print("DEBUG: Failed with error \(error)")
}
转换为 [评论] -> [用户] -> ([评论], [用户]) -> [附有用户的评论]
推荐阅读
- python - 获取字典键的值作为字典列表中的列表,无需循环
- python - 使用 Pandas df 将研发费用资本化
- python - 将 2D 元组重塑为 1D
- ios - 如何使枚举可编码?
- python - OSError: [WinError 123] 文件名、目录名或卷标语法不正确:'D:\\cat-and-dog\training_set\training_set'
- amazon-web-services - 使用 kubectl 访问 AWS 时出现 SSL 问题
- wcf - WCF:方法返回一个响应,在产生一个线程做后台处理之后
- java - 连接到删除主机时apache FTP客户端连接超时
- c# - MVC Razor 检查无线电输入以启用
- python - 将 gRPC 与 gevent 一起使用