Ios 嵌套的完成块是否是不良设计的标志?
我有一个方法调用三个函数,每个函数向Firebase发出请求,并在完成处理程序中传回数据。一旦来自两个完成处理程序的数据被发回,我调用另一个方法来传入数据并发回一个有效的结果。像这样的嵌套块是设计拙劣的标志吗Ios 嵌套的完成块是否是不良设计的标志?,ios,swift,oop,asynchronous,completionhandler,Ios,Swift,Oop,Asynchronous,Completionhandler,我有一个方法调用三个函数,每个函数向Firebase发出请求,并在完成处理程序中传回数据。一旦来自两个完成处理程序的数据被发回,我调用另一个方法来传入数据并发回一个有效的结果。像这样的嵌套块是设计拙劣的标志吗 func fetchNearbyUsers(for user: User, completionHandler: usersCompletionHandler?) { self.fetchAllUsers(completionHandler: { (use
func fetchNearbyUsers(for user: User, completionHandler: usersCompletionHandler?) {
self.fetchAllUsers(completionHandler: { (users: [User]) in
ChatProvider.sharedInstance.fetchAllChatrooms(completionHandler: { (chatrooms: [Chatroom]) in
self.validateNewUsers(currentUser: user, users: users, chatrooms: chatrooms, completionHandler: { (validUsers: [User]) in
guard validUsers.isEmpty == false else {
completionHandler?([])
return
}
completionHandler?(validUsers)
})
})
})
}
//其他方法
func fetchAllUsers(completionHandler: usersCompletionHandler?) {
var users: [User] = []
let group = DispatchGroup()
let serialQueue = DispatchQueue(label: "serialQueue")
DatabaseProvider.sharedInstance.usersDatabaseReference.observe(.value, with: {
snapshot in
guard let data = snapshot.value as? [String: AnyObject] else { return }
for (_, value) in data {
guard let values = value as? [String: AnyObject] else { return }
guard let newUser = User(data: values) else { return }
group.enter()
newUser.fetchProfileImage(completionHandler: { (image) in
serialQueue.async {
newUser.profileImage = image
users.append(newUser)
group.leave()
}
})
}
group.notify(queue: .main, execute: {
completionHandler?(users)
})
})
}
func fetchAllChatrooms (completionHandler: chatroomsHandler?) {
var chatrooms = [Chatroom]()
let group = DispatchGroup()
let serialQueue = DispatchQueue(label: "serialQueue")
DatabaseProvider.sharedInstance.chatroomsDatabaseReference.observe(.value, with: { snapshot in
guard let data = snapshot.value as? [String: AnyObject] else { return }
for (_, value) in data {
guard let value = value as? [String: AnyObject] else { return }
guard let newChatroom = Chatroom(data: value) else { return }
group.enter()
self.fetchChatroomUsers(chatroom: newChatroom, completionHandler: { (chatroom) in
serialQueue.async {
chatrooms.append(newChatroom)
group.leave()
}
})
}
group.notify(queue: .main, execute: {
completionHandler?(Array(Set<Chatroom>(chatrooms)))
})
})
}
private func validateNewUsers(currentUser: User, users: [User], chatrooms: [Chatroom], completionHandler: usersCompletionHandler?) {
let chatPartners = self.chatPartners(currentUser: currentUser, chatrooms: chatrooms)
let validUsers = users
.filter { currentUser.id != $0.id }
.filter { currentUser.distanceFromUser(atLocation: $0.coordinates) <= 8046.72 }
.filter { !chatPartners.contains($0.id) }
completionHandler?(validUsers)
}
private func chatPartners (currentUser: User, chatrooms: [Chatroom]) -> Set<String> {
var results = [String]()
for chatroom in chatrooms {
if currentUser.id == chatroom.firstUserId {
results.append(chatroom.secondUserId)
} else if currentUser.id == chatroom.secondUserId {
results.append(chatroom.firstUserId)
}
}
return Set(results)
}
func fetchAllUsers(completionHandler:usersCompletionHandler?){
变量用户:[用户]=[]
let group=DispatchGroup()
让serialQueue=DispatchQueue(标签:“serialQueue”)
DatabaseProvider.sharedInstance.usersDatabaseReference.observe(.value,带:{
快照
guard let data=snapshot.value as?[String:AnyObject]else{return}
对于数据中的(_,值){
guard let values=值为?[String:AnyObject]else{return}
guard let newUser=User(数据:值)else{return}
group.enter()
fetchProfileImage(completionHandler:{(图像)位于
serialQueue.async{
newUser.profileImage=image
users.append(newUser)
小组请假()
}
})
}
通知组(队列:.main,执行:{
completionHandler?(用户)
})
})
}
func fetchall聊天室(completionHandler:chatroomsHandler?){
var聊天室=[Chatroom]()
let group=DispatchGroup()
让serialQueue=DispatchQueue(标签:“serialQueue”)
DatabaseProvider.sharedInstance.chatroomsDatabaseReference.observe(.value,带:{snapshot in
guard let data=snapshot.value as?[String:AnyObject]else{return}
对于数据中的(_,值){
guard let value=值为?[String:AnyObject]else{return}
guard let newChatroom=聊天室(数据:值)else{return}
group.enter()
self.fetchChatroomUsers(聊天室:newChatroom,completionHandler:{(聊天室)在
serialQueue.async{
聊天室。附加(新聊天室)
小组请假()
}
})
}
通知组(队列:.main,执行:{
completionHandler?(数组(集合(聊天室)))
})
})
}
private func validateNewUsers(当前用户:用户,用户:[用户],聊天室:[聊天室],completionHandler:usersCompletionHandler?){
让chatPartners=self.chatPartners(当前用户:当前用户,聊天室:聊天室)
让validUsers=用户
.filter{currentUser.id!=$0.id}
.filter{currentUser.distanceFromUser(atLocation:$0.coordinates)集合{
变量结果=[String]()
聊天室中的聊天室{
如果currentUser.id==chatroom.firstUserId{
results.append(chatroom.secondUserId)
}如果currentUser.id==chatroom.secondUserId,则为else{
results.append(chatroom.firstUserId)
}
}
返回集(结果)
}
不一定,但除非它们非常简单,否则它们应该是作为参数传递的专用方法。复杂的嵌套闭包很难推理,也很难调试,因此我们强烈反对在实践中使用它。@Joshatternerry,我想我的方法对于嵌套闭包来说太复杂了。关于w如果您愿意进行重构,我将不胜感激。我正在努力在编写干净的代码和使事情正常运行之间找到平衡。有一个专门的SE页面用于代码审查:。虽然您的问题似乎在这里,但您可能也会在那里得到很好的见解。