如何更改触发函数的顺序?

How can I change the order of functions triggered?

我正在 Swift 编码,我的代码有问题。 在下面的代码中,我试图先获取 table 视图单元格的信息,然后执行转场。我也在使用 Firestore 来保存数据。问题是当我使用 print 时,我可以先看到 segue triggered!!!,然后看到 document saved!!。由于我想将doc.documentID的值传递给下一个视图控制器,所以我想在触发执行转场之前保存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)
                }
            }
            }
        
        }

    }
}

数据从 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)
                }
            }
            
        }
    }
    }
}

另见:

  • ,使用调度组貌似改变了执行顺序。