【问题标题】:How to execute tasks sequentially? Swift3如何按顺序执行任务?斯威夫特3
【发布时间】:2017-07-07 15:09:04
【问题描述】:

在 else 语句中的 @IBaction func login 内部,我调用 startObserving()。为什么不在主线程上执行?
这条语句print("executed")self.startObservingDB(callback: { (snapValue) in 中的代码在else 语句中被求值之前被执行。 我不希望 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

【问题讨论】:

    标签: ios swift3 grand-central-dispatch completionhandler


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 如何让我的方法 startObservingDB 等到 Thread B: Executes callback(snapshot.value as? FIRDataSnapshot) 完成?我需要在self.startObservingDB(callback: { (snapValue) in 中检查if snapValue != nil,我假设为了实现这一点,我必须让startObservingDB 等到firebase 完成工作。谢谢
    • 我认为您只是对块的工作方式存在误解,您已经得到了刚才提到的行为。当callback(snapshot.value as? FIRDataSnapshot) 执行时,它正在运行您通过此调用self.startObservingDB(callback: { (snapValue) in 传入的块。它们是同一段代码,就像调用一个方法运行该方法中的代码一样。
    猜你喜欢
    • 2017-03-24
    • 1970-01-01
    • 1970-01-01
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    • 2017-05-26
    • 1970-01-01
    相关资源
    最近更新 更多