如何顺序执行任务?斯威夫特3

How to execute tasks sequentially? Swift3

@IBaction func login 内的 else 语句中,我调用 startObserving()。为什么不在主线程执行?
此语句 print("executed")self.startObservingDB(callback: { (snapValue) in 中的代码在 else 语句中计算之前执行。 我不希望 startObservingDB 在收到来自 Firebase 的 snapValue 之前 return。如何让else语句中的startObservingDB等待Firebase任务完成后再继续执行?

@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

对 startObservingDB 的调用 IS 发生在同一个线程上。

但是,您会注意到对 observeSingleEvent 的调用需要一个回调。这是因为该调用在内部启动了一个新的后台线程。该方法一旦完成,将返回并调用您的回调。

所以您看到的事件顺序是:

  • 线程 A:startObservingDB 启动
  • 线程 A:observeSingleEvent 开始
  • 线程 B:开始为 observeSingleEvent 做内部工作
  • 线程 A:observeSingleEvent returns
  • 线程 A:startObservingDB returns
  • 线程 A:打印("executed")
  • 线程 B:完成 observeSingleEvent 的内部工作
  • 线程 B:在 observeSingleEvent
  • 上执行来自 "with" 的回调
  • 线程 B:执行回调(snapshot.value as?FIRDataSnapshot)
  • 线程 B:打印("should segue")
  • 线程 B:performSegue