嵌套完成块是否是设计错误的标志?

时间:2017-06-06 01:34:37

标签: ios swift oop asynchronous completionhandler

我有一个方法可以调用三个函数,每个函数向Firebase发出请求并在完成处理程序中传回数据。一旦完成了来自2个完成处理程序的数据,我就会调用另一个方法传入数据并发回有效结果。像这样的嵌套块是设计不佳的标志吗?

    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)
}

0 个答案:

没有答案