2017-07-07 3 views
0

À l'intérieur @IBaction func login dans l'autre instruction, j'appelle startObserving(). Pourquoi n'est-il pas exécuté sur le thread principal?
Cette instruction print("executed") est exécutée avant que le code self.startObservingDB(callback: { (snapValue) in soit évalué dans l'instruction else. Je ne veux pas que startObservingDB retourne avant de recevoir snapValue de Firebase. Comment faire pour que startObservingDB dans l'instruction else attende que Firebase termine ses tâches et continue l'exécution?Comment exécuter les tâches de manière séquentielle? Swift3

@IBAction func logIn(_ sender: AnyObject) { 

    FIRAuth.auth()?.signIn(withEmail: email.text!, password: password.text!, completion: { (authData, error) in 

    if error != nil { 
      // 
     } else { 
     self.startObservingDB(callback: { (snapValue) in 
     if snapValue != nil { 
      print("should segue") 
       self.performSegue(withIdentifier: "LogInToTabBarController", sender: self) 
        } 
       })//end of startObservingDB 


//prints before code in else statement, inside self.startObservingDB(callback: { (snapValue) is evaluated 
print("executed") 
     } 
    }) 
} 



func startObservingDB(callback:@escaping ((_ snapShot:FIRDataSnapshot?) -> Void)){ 
    // check if user is singed in 
    guard let uid = FIRAuth.auth()?.currentUser?.uid else { 
     return 
    } 

    dbRef.child(uid).child("profile").observeSingleEvent(of: .value, with: { (snapshot: FIRDataSnapshot) in 

     //pass snapshot vale to callback closure so as to make the values available when calling startObservingDB 
     callback(snapshot.value as? FIRDataSnapshot) 


    }, withCancel: { (Error:Any) in 
     print("Error firebase \(Error)") 
     print("You are not a cleaner") 

    }) 
    dbRef.removeAllObservers() 
} // end of startObserving 

Répondre

0

L'appel à startObservingDB IS passe sur le même fil. Cependant, vous remarquerez que l'appel à observerSingleEvent prend un rappel. C'est parce que cet appel lance en interne un nouveau thread d'arrière-plan. Cette méthode, une fois terminée, reviendra et appellera votre callback.

Ainsi, la séquence des événements que vous voyez est:

  • Discussion A: startObservingDB commence
  • Discussion A: observeSingleEvent commence
  • Discussion B: commence à faire le travail interne pour
  • observeSingleEvent
  • Discussion A: observeSingleEvent renvoie
  • Thread A: startObservingDB renvoie
  • Thread A: print ("exécuté «)
  • Discussion B: Les apprêts faire un travail interne pour observeSingleEvent
  • Discussion B: Exécute le rappel de la "avec" sur observeSingleEvent
  • Discussion B: rappel Exécute (comme snapshot.value? FIRDataSnapshot)
  • Sujet B: print ("devrait segue")
  • Discussion B: performSegue
+0

Comment puis-je faire ma méthode startObservingDB d'attendre jusqu'à ce que 'B Discussion: rappel Exécute (snapshot.value comme FIRDataSnapshot?) 'finit? Je dois vérifier 'si snapValue! = Nil' dans' self.startObservingDB (callback: {(snapValue) in' et je suppose que pour que cela se produise, je dois faire 'startObservingDB' attendre que firebase ait fini le travail. Merci – bibscy

+0

Je pense que vous avez juste un malentendu sur le fonctionnement des blocs, vous obtenez déjà le comportement que vous venez de mentionner Quand 'callback (snapshot.value as? FIRDataSnapshot)' s'exécute, il exécute le bloc que vous avez passé avec cet appel 'self.startObservingDB (callback: {(snapValue) in.) Ils sont le même morceau de code, comme l'appel d'une méthode exécute le code dans cette méthode. –