2017-07-07 86 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'),它们是同一段代码,就像调用方法来运行该方法中的代码一样。 –