如何等待快速读取数据库的结果?

Posted

技术标签:

【中文标题】如何等待快速读取数据库的结果?【英文标题】:How to wait for the result of a database read in swift? 【发布时间】:2021-08-17 00:30:36 【问题描述】:

在我的应用程序中,我使用 Firebase 实时数据库来存储有关用户的数据。我想确保当我读取这些数据以在视图中显示它(例如他们的昵称)时,在显示它之前已经完成了读取。让我解释一下:

//Initialization of user properties
    static func initUsers()
        let usersref = dbRef.child("Users").child(userId!)
        usersref.observeSingleEvent(of: .value)  (DataSnapshot) in
            if let infos = DataSnapshot.value as? [String : Any]
                self.username = infos["username"] as! Int
                 
                //The VC is notified that the data has been recovered
                let name = Notification.Name(rawValue: "dataRetrieved")
                let notification = Notification(name: name)
                NotificationCenter.default.post(notification)
            
        
    

这是在模型中运行并在用户登录时读取用户数据的代码。

var isFirstAppearance = true
 
override func viewDidLoad() 
        super.viewDidLoad()
         
        //We initialise the properties associated with the user
        Users.initUsers()
    
     
    override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(animated)
        if isFirstAppearance 
            let name = Notification.Name(rawValue: "dataRetrieved")
            NotificationCenter.default.addObserver(self, selector: #selector(registerDataToView), name: name, object: nil)
            isFirstAppearance = false
        
        else
            registerDataToView()
        
    
 
    //The user's data is assigned to the view
    @objc func registerDataToView()
        usernameLabel.text = String(Users.username)
    

我们在 VC 中,当视图加载时,我们在 viewDidLoad 中调用 initUsers。在 viewWillAppear 中,如果这是我们第一次加载视图,那么我们创建一个侦听器,如果数据库中的读取完成,它会调用 registerDataToView。否则我们只需调用 registerDataToView (这是在我们返回此 VC 时更新标签)。

我想知道是否有可能,例如当我们的连接非常糟糕时,侦听器不会拦截 dataRetrieved 通知,因此我的 UI 只显示默认文本?还是耳机在继续之前等待接收通知?

如果不等待,那么在初始化标签之前如何等待数据库读取完成?

感谢您的宝贵时间 :)

【问题讨论】:

【参考方案1】:

别等了。永远不要等待。告诉接收者数据可用完成处理程序

static func initUsers(completion: @escaping (Bool) -> Void) 
    let usersref = dbRef.child("Users").child(userId!)
    usersref.observeSingleEvent(of: .value)  (DataSnapshot) in
        if let infos = DataSnapshot.value as? [String : Any]
            self.username = infos["username"] as! Int
            completion(true)
            return
        
        completion(false)
    
    

并使用它

override func viewDidLoad() 
    super.viewDidLoad()
     
    //We initialise the properties associated with the user
    Users.initUsers  [unowned self] result in
        if result (
          // user is available 
         else 
          // user is not available 
        
    

【讨论】:

谢谢,但是如果用户连接不好,我如何让他等待数据被读取,以便我可以在视图中显示它。否则 UI 将不完整。如果阅读需要时间,我曾想过将相关标签隐藏起来,当阅读完成时,我会用相关数据显示它们。这是一个好的解决方案吗?

以上是关于如何等待快速读取数据库的结果?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 等待事件:您如何解释 db 文件分散/顺序读取?

在返回结果之前等待 AsyncTask.execute(()) 完成

OpenSSL等待读取数据可用

Go 读取大文件

java读取一个10G大小的文本文件,怎么才能快速的得到该文本文件里面长度最长的单词?

Java以行的方式,快速读取大文件的2种实现方法,附完整代码和测试结果