如何更改触发功能的顺序?

Posted

技术标签:

【中文标题】如何更改触发功能的顺序?【英文标题】:How can I change the order of functions triggered? 【发布时间】:2020-08-18 16:27:18 【问题描述】:

我正在编写 Swift 编码,但我的代码中有问题。 在下面的代码中,我试图先获取表格视图单元格的信息,然后执行 segue。我也在使用 Firestore 来保存数据。问题是当我使用打印时,我可以先看到segue triggered!!!,然后再看到document saved!!。因为我想将doc.documentID的值传递给下一个视图控制器,所以我想在触发执行segue之前保存documentID.....

class HomeViewController: UIViewController 
    var gameDocumentID = ""
// more codes here...
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    if segue.identifier == K.homeToGameScreen 
            let gameScreenVC = segue.destination as! GameScreenViewController

                gameScreenVC.gameDocumentID = gameDocumentID
        
    



        extension HomeViewController: UITableViewDelegate 
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 

    // serch game db where player1 is ready to play
    
    db.collection(K.FStore.newGameCpllection).whereField(K.FStore.uID, isEqualTo: players[indexPath.row].uID).addSnapshotListener  (querySnapshot, err) in
        if let err = err 
            print("Error getting game db: \(err)")
         else 
            
            for doc in querySnapshot!.documents 
                
                print("document saved!!")
                self.gameDocumentID = doc.documentID
            
            self.db.collection(K.FStore.newGameCpllection).document(self.gameDocumentID).updateData([
                K.FStore.player2Field: self.playerInfo[K.FStore.nameField]!
            ])  err in
                if let err = err 
                    print("Error updating document: \(err)")
                 else 
                    print("Document successfully updated")
                    
                
                print("segue triggered!!!")
                self.performSegue(withIdentifier: K.homeToGameScreen, sender: self)
                
            
            
        
        

    

【问题讨论】:

【参考方案1】:

数据是从 Firebase 异步加载的。由于这可能需要一些时间,因此您的完成处理程序的调用时间比您预期的要晚。

因此,任何需要数据库数据的代码都需要在完成处理程序中,或者从那里调用。

所以最简单的解决方法是将performSegue 移动到回调中:

extension HomeViewController: UITableViewDelegate 
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 

    db.collection(K.FStore.newGameCpllection)
      .whereField(K.FStore.uID, isEqualTo:players[indexPath.row].uID)
      .addSnapshotListener  (querySnapshot, err) in
            if let err = err 
                print("Error getting game db: \(err)")
             else 
                for doc in querySnapshot!.documents 
            
                print("document saved!!")
                self.gameDocumentID = doc.documentID                
                self.db.collection(K.FStore.newGameCpllection).document(self.gameDocumentID).updateData([
                    K.FStore.player2Field: self.playerInfo[K.FStore.nameField]!
                ])  err in
                    if let err = err 
                        print("Error updating document: \(err)")
                     else 
                        print("Document successfully updated")
                    
                    print("segue triggered!!!")
                    self.performSegue(withIdentifier: K.homeToGameScreen, sender: self)
                
            
            
        
    
    

另见:

Is Firebase getDocument run line by line? Handling asynchronous Firestore data reading in tableView - ios Storing asynchronous Cloud Firestore query results in Swift,使用调度组来改变执行顺序。 How do I save data from cloud firestore to a variable in swift?

【讨论】:

谢谢弗兰克。实际上,我已经尝试过了。在这种情况下,问题是 preformSegue 被触发了两次,我可以看到下一个视图控制器移动了两次......这很奇怪,因为我认为它在 querySnapshot!.documents 循环中的 for doc 之外,并且没有真正触发 segue.. . 啊,我看到您也缺少快照侦听器中的嵌套。我更新了我的答案以嵌套听众。但是您最好使用getDocument() 调用而不是addSnapshotListener 调用:firebase.google.com/docs/firestore/query-data/… 嗯。它仍然显示下一个视图控制器两次。在当前的视图控制器中,我也有准备功能,我看到有人说这可能是我两次获得 vc 的原因。但是即使我把prepare函数注释掉了,还是一样... 如果嵌套后还有两个回调,你试过getDocument()吗? 好的。现在它起作用了。不再有 getDocument() 并且不得不使用 getDocuments,我认为这将是一个以上的文档,但在我的情况下似乎不是......非常感谢您的帮助!

以上是关于如何更改触发功能的顺序?的主要内容,如果未能解决你的问题,请参考以下文章

Spotify 应用程序:更改位置时触发功能

通过一个功能以编程方式迅速触发多个按钮

更改功能不会在 iOS 上触发

如何确定哪个小部件触发了插槽功能?

过滤器功能(过滤器)的第一次更改不会触发 onChange [重复]

如何通过 cli / rest api / cloud 功能运行 Google Cloud Build 触发器?