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



我在下面提供的代码中有一系列嵌套的完成块。这是因为我需要在背景中提出单独的网络请求,以在下一个方法中使用抽象数据,该方法提供了另一个完成块,依此类推。有没有办法解决?任何提示都非常感谢!

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

这里的一个选项是使用高阶工厂功能(即返回其他功能的函数(将块分解为自己的功能...

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

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

还要注意,我更改了您的fetchNearbyUsers功能以接受一个完成块,默认为一个无用的块而不是使用可选块。对我来说感觉更干净。

为什么不调用功能并使用一些布尔来确保两者都完成。这是一些伪代码

var completeA = false
var completeB = false
func doStuff {
    asyncStuffA(stuff {
        asyncStuffB(stuff {
            }, completion: {
                completeB = true
                completionHandler()
        })
        }, completion: {
            completeA = true
            completionHandler()
    })
}

func completionHandler() {
    if completeA && completeB {
        // Both are complete
        completeA = false
        completeB = false
    }
}

最新更新