Делать вещи в последовательности, используя обработчики завершения - PullRequest
0 голосов
/ 04 января 2019

У меня есть три функции, которые необходимо выполнить в следующей последовательности:

  1. Соберите целые числа из Firebase, поместите их в массив и вычислите сумму.После завершения ...
  2. Соберите другое целочисленное значение из Firebase.После завершения ...
  3. Третья функция берет значение из функции 2 и вычитает его из функции 1.

Я знаю, что мне нужно использовать обработчики завершения, но нужна некоторая помощьс синтаксисом и т. д.

// Эта первая функция получает целые числа из Firebase и суммирует их:

func LoadPointsCompleted(completion: @escaping(_ sumOfPointsCompleted:Int) -> Int){

    self.challengeList.removeAll()

    databaseReference = Database.database().reference()

    let userID = Auth.auth().currentUser?.uid

    let refChallenges = Database.database().reference(withPath: "Challenges").child(userID!).queryOrdered(byChild: "Status").queryEqual(toValue: "Complete")

    refChallenges.observeSingleEvent(of: .value, with: { (snapshot) in

        //if the reference have some values
        if snapshot.childrenCount > 0 {

            //clearing the list
            self.challengeList.removeAll()



            //iterating through all the values
            for Challenges in snapshot.children.allObjects as! [DataSnapshot] {
                //getting values
                let challengeObject = Challenges.value as? [String: AnyObject]
                let Points = challengeObject?["Points"] as! Int

                //creating challenge object with model and fetched values
                let challenge = pointsModel(Points: (Points as Int?)!)

                //appending it to list
                self.challengeList.append(challenge)


                let sumOfPointsCompleted = self.challengeList.reduce(0) {$0 + $1.Points}

                let sumOfPointsCompletedString = String(sumOfPointsCompleted)
                self.Calc_Earned.text = sumOfPointsCompletedString

                completion(sumOfPointsCompleted)

            }

        }

    }

    )}

// Эта вторая функция просто получает целое значение из другого местоположения в Firebase

func loadPointsRedeemed(completion: @escaping (_ Points_Redeem: Int) -> Int) {


    databaseReference = Database.database().reference()

    let userID = Auth.auth().currentUser?.uid

    databaseReference.child("Users").child(userID!).observe(DataEventType.value, with: { (snapshot) in

        let value = snapshot.value as? NSDictionary

        // let Points_Earn = value?["Points_Earned"] as? String ?? ""
        let Points_Redeem = value?["Points_Redeemed"] as! Int


        // self.Points_Earned.text = Points_Earn

        let points_redeemedString = String(Points_Redeem)
        self.Points_Redeemed.text = points_redeemedString

        // let pointsRedeemedAs = Points_Redeem

        completion(Points_Redeem)

        // Do any additional setup after loading the view.
    }

)}

// Эта третья функция просто берет значения из первых двух функций и вычитает их

 func BalanceOfPoints(){

    let a = LoadPointsCompleted()
    let b = loadPointsRedeemed()


    let balance = a - b
    let balanceString = String(balance)

    self.Points_Balance.text = balanceString

}

Однако в третьей функции "BalanceOfPoints" я получаю некоторые ошибки следующим образом:

Отсутствует аргумент для параметра «завершение» в вызове - вставить «завершение»: <(Int) -> Int> '

Я не знаю, правильный ли мой синтаксис при первом запускездесь работает так:

func LoadPointsCompleted(completion: @escaping(_ sumOfPointsCompleted:Int) -> Int){

и ...

func loadPointsRedeemed (завершение: @escaping (_ Points_Redeem: Int) -> Int) {

Может кто-топожалуйста помоги?Заранее спасибо.

1 Ответ

0 голосов
/ 04 января 2019

LoadPointsCompleted принимает закрытие в качестве аргумента (обработчик завершения)

вы можете либо дать ему nil обработчик завершения

LoadPointsCompleted(completion: nil)

, либо дать ему обработчик

LoadPointsCompleted() { sumOfPointsCompleted in

    return <#some Int#>
}

но ваша логика в BalanceOfPoints выглядит немного не так, потому что LoadPointsCompleted и loadPointsRedeemed вызываются последовательно в одно и то же время и также фактически не возвращают Int, только обработчик завершенияфункция делает.например, completion(sumOfPointsCompleted) можно изменить на let a = completion(sumOfPointsCompleted), но я уверен, что это не то, что вы намеревались.

Я бы изменил сигнатуру обеих этих функций на

func LoadPointsCompleted(completion: @escaping(_ sumOfPointsCompleted:Int) -> Void){

и

func loadPointsRedeemed(completion: @escaping (_ Points_Redeem: Int) -> Void) {

, затем в BalanceOfPoints сделайте это вместо

func BalanceOfPoints(){

    LoadPointsCompleted() { sumOfPointsCompleted in
        loadPointsRedeemed() { Points_Redeem in
            let balance = sumOfPointsCompleted - Points_Redeem
            let balanceString = String(balance)

            self.Points_Balance.text = balanceString
        }
    }
}

, но просто отметьте, что BalanceOfPoints в настоящее время асинхронная функция.

Не уверен, что шаг 1 и 2в вашем вопросе может быть сделано параллельно, но кажется, что они могли бы быть, но, как оно стоит в этом ответе, они в последовательности

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...