2017-07-07 87 views
0

Inside @IBaction func login in else statement我打電話給startObserving()。爲什麼它不在主線程上執行?
在else語句中計算self.startObservingDB(callback: { (snapValue) in中的代碼之前執行此語句print("executed")。 我不希望startObservingDB在它從Firebase接收到snapValue之前返回。如何在else語句中使startObservingDB等待Firebase完成其任務並繼續執行?如何順序執行任務? 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 

回答

0

到startObservingDB 的調用是發生在同一個線程。

但是,您會注意到對observeSingleEvent的調用需要回調。這是因爲內部調用啓動了一個新的後臺線程。該方法一旦完成,就會恢復,然後調用你的回調函數。

所以你看到事件的順序是:

  • 線程A:startObservingDB開始
  • 線程A:observeSingleEvent開始
  • 線程B:開始做內部工作observeSingleEvent
  • 主題A:observeSingleEvent返回
  • 線程A:startObservingDB返回
  • 線程A:print(「executed與 「上observeSingleEvent「)
  • 線程B:完成將做對observeSingleEvent
  • 線程B的內部工作從執行回調」
  • 線程B:執行回調(如snapshot.value? FIRDataSnapshot)
  • 線程B:打印( 「應該Segue公司」)
  • 線程B:performSegue
+0

我怎樣才能讓我的方法startObservingDB等到'線程B:執行回調(如snapshot.value FIRDataSnapshot? )完成?我需要在self.startObservingDB(callback:{(snapValue)in')中檢查'snapValue!= nil',我假設爲了實現這個目的,我必須讓'startObservingDB'等到firebase完成工作。謝謝 – bibscy

+0

我覺得你對塊的工作方式有誤解,你已經得到了剛纔提到的行爲,當'callback(snapshot.value as?FIRDataSnapshot)'執行時,它會運行你傳入的塊這個調用'self.startObservingDB(callback:{(snapValue)in'),它們是同一段代碼,就像調用方法來運行該方法中的代碼一樣。 –