处理程序在for循环完成之前迅速调用Firebase snasphot之前就被调用,为什么?

时间:2018-10-25 01:28:39

标签: swift

我需要一些帮助,我有以下代码,该代码是函数的一部分,该函数从snapshot查询并返回Firebase用户数据。我正在尝试遍历snapshot并将其传递给辅助过滤器(帮助过滤)的辅助方法filterDiscoveredUserByPreferences,然后假设将对象添加到数组中,以便可以将其通过handler

问题在于,我的handlerfor循环完成从Firebase返回的快照之前被调用得太早了。我曾尝试使用distpatchQueue,但没有用。

self.getUsersAtVenueHandle = self.REF_USERS.observe(.value, with: { (snapshot) in

                    guard let usersSnapshot = snapshot.children.allObjects as? [DataSnapshot] else { return }


                        for user in usersSnapshot{
                            // Code here to get all values from ‘user’ snapshot the create User object

                            let user = User(uid: uid, dictionary: dictionary)

                            if user.discoverable == true && user.uid != Auth.auth().currentUser?.uid {

                                self.filterDiscoveredUserByPreferences(discoveredUser: user, handler: { (success) in

                                    if success {
                                        users.append(user)
                                    }

                                })//filterDiscoveredUserByPreferences

                            }//end if

                        }//end for

                        //handler gets called before for loops has finished processing the entire snapshot

                        handler (users, true)
                        users.removeAll()


                }, withCancel: { (error) in
                    print(error)

                })//end Firebase call

功能:filterDiscoveredUserByPreferences

func filterDiscoveredUserByPreferences(discoveredUser: User, handler: @escaping (Bool) -> ()){

    let discoveredGender = discoveredUser.gender
    let discoveredPrefs: [String : Any] = discoveredUser.discoveryPrefs
    let discoveredPreferMen = discoveredPrefs["men"] as? Bool
    let discoveredPreferWomen = discoveredPrefs["women"] as? Bool

    var discoveredPreferredGender: String?

    switch (discoveredPreferMen, discoveredPreferWomen) {

    case (true, true):
        discoveredPreferredGender = "both"

    case (true, false):
        discoveredPreferredGender = "female"

    case (false, true):
        discoveredPreferredGender = "male"

    case (false, false):
        discoveredPreferredGender = "not discoverable"

    default:
        break
    }//end switch


    getUserInfo(forUserId: (Auth.auth().currentUser?.uid)!) { (user) in

        let myGender = user.gender
        let myDiscoveryPrefs: [String : Any] = user.discoveryPrefs
        let myPreferMen = myDiscoveryPrefs["men"] as? Bool
        let myPreferWomen = myDiscoveryPrefs["women"] as? Bool


        switch (myPreferWomen, myPreferMen) {

        case (true, true): //both

            switch myGender {

            case "male":

                switch(discoveredPreferredGender){

                case "male":
                    handler(true)

                case "female":
                    handler(false)

                case "both":
                    handler(true)

                case "not discoverable":
                    handler(false)

                default:
                    break

                }//end switch

            case "female":

                switch(discoveredPreferredGender){

                case "male":
                    handler(false)

                case "female":
                    handler(true)

                case "both":
                    handler(true)

                case "not discoverable":
                    handler(false)

                default:
                    break

                }//end switch

            default:
                break

            }//end switch



        case (true, false)://female only

            if discoveredGender == "male"{
              handler(false)
            } else {

                switch(discoveredPreferredGender){

                case "male":
                    handler(true)

                case "female":
                    handler(false)

                case "both":
                    handler(true)

                case "not discoverable":
                    handler(false)

                default:
                    break

                }//end switch

            }//end else

        case (false, true): //male only

            if discoveredGender == "female"{
                handler(false)
            } else {

                switch(discoveredPreferredGender){

                case "male":
                    handler(true)

                case "female":
                    handler(false)

                case "both":
                    handler(true)

                case "not discoverable":
                    handler(false)

                default:
                    break

                }//end switch

            }//end else

        case (false, false): //none

            handler(false)

        default:
            break
        }


    }//end getLoggedinUserDetails


}//end fun

Func getUserInfo

func getUserInfo(forUserId: String, currentUserHandler: @escaping (_ currentUser: User) -> ()){

    REF_USERS.child(uid).observe(.value, with: { (snapshot) in

        guard let dict = snapshot.value as? [String: Any] else { return }

        let user = User(uid: uid, dictionary: dict)

        currentUserHandler(user)

    }) { (error) in
        print(error)
    }

}//end func

1 个答案:

答案 0 :(得分:0)

这是异步回叫,根据更新情况,它将被多次调用。 如果使用调试断点进行检查,则可能会感到困惑。在observe(.value, with: { (snapshot) }闭包的开始和结束处编写控制台日志,您将了解流程。在完成for循环之前不可能调用处理程序。 可能是您的第一个回调具有大量记录,而第二个回调具有零个DataSnapshot s