如何顺序执行任务? Swift3

时间:2017-07-07 15:09:05

标签: ios swift3 grand-central-dispatch completionhandler

在else语句中的@IBaction func login内,我调用了startObserving()。为什么不在主线程上执行?
在else语句中计算print("executed")内的代码之前执行此语句self.startObservingDB(callback: { (snapValue) in。 我不希望startObservingDB在从Firebase接收snapValue之前返回。如何在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

1 个答案:

答案 0 :(得分:0)

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

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

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

  • 线程A:startObservingDB启动
  • 线程A:observeSingleEvent启动
  • 线程B:开始为observeSingleEvent进行内部工作
  • 线程A:observeSingleEvent返回
  • 线程A:startObservingDB返回
  • 主题A:打印(“已执行”)
  • 主题B:完成对observeSingleEvent的内部工作
  • 线程B:执行来自observeSingleEvent
  • 的“with”的回调
  • 线程B:执行回调(snapshot.value为?FIRDataSnapshot)
  • 线程B:print(“should segue”)
  • 主题B:performSegue