如何防止Swift 3中的嵌套完成块?

6 nested completionhandler swift

我在下面提供的代码中有一系列嵌套的完成块。这是因为我需要在后台发出单独的网络请求,以提取要在下一个方法中使用的数据,该方法提供了另一个完成块,依此类推。有没有办法解决?任何提示,不胜感激!

func fetchNearbyUsers(forCurrentUser 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)
            })
        })
    })
} 
Run Code Online (Sandbox Code Playgroud)

Dan*_* T. 6

这里的一种选择是使用高阶工厂函数(即返回其他函数的函数)将块分解成它们自己的函数......

func fetchNearbyUsers(forCurrentUser user: User, completionHandler: @escaping usersCompletionHandler = { _ in }) {      
    self.fetchAllUsers(completionHandler: self.allUsersFromChatrooms(user: user, completionHandler: completionHandler))
}

func allUsersFromChatrooms(user: User, completionHandler: @escaping usersCompletionHandler) -> ([User]) -> Void {
    return { users in
        ChatProvider.sharedInstance.fetchAllChatrooms(completionHandler: self.validatedUsersInChatrooms(user: user, users: users, completionHandler: completionHandler))
    }
}

func validatedUsersInChatrooms(user: User, users: [User], completionHandler: @escaping usersCompletionHandler) -> ([Chatroom]) -> Void {
    return { chatrooms in
        self.validateNewUsers(currentUser: user, users: users, chatrooms: chatrooms, completionHandler: completionHandler)
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,validatedUsersInChatrooms将返回一个函数,该函数接受一组聊天室,并使用经过验证的用户调用提供的完成处理程序。该函数allUsersFromChatrooms返回一个接受用户数组的函数,然后获取聊天室并使用聊天室中经过验证的用户数组调用提供的完成处理程序。

另请注意,我将您的fetchNearbyUsers函数更改为接受完成块并默认为一个不执行任何操作的块,而不是使用可选块。对我来说感觉干净多了。