如何修复异步问题的firebase问题



我试图查询数据并将数据更新为firebase。但是我无法获取数据。看来该程序没有遇到参考我应该做什么来解决这个问题?

    func getId(path:String, value:String?, completion: @escaping (String?) -> Void) {
        let ref = Database.database().reference(withPath: path).queryOrdered(byChild: "name").queryEqual(toValue: value)
        ref.observeSingleEvent(of: .childAdded, with: { snapshot in
            print("running in getId")
            completion(snapshot.key)                
        }) { (error) in
            print(error.localizedDescription)
        }
    }
@objc func onTapConfirmed(){
     self.getId(path: "patients", value: self.kardex?.patient?.name) { snapshotKey in
      BookingViewController.kardexDict["patient"] = snapshotKey as AnyObject?
      print("1:get patient name")
      }
     self.getId(path: "nurses", value: BookingTreatmentListController.nurseName) { snapshotKey in
      BookingViewController.kardexDict["nurse"] = snapshotKey as AnyObject?
      print("2:get nurse name")
      }
      Database.database().reference().child("kardexes").child(BookingViewController.newKardex.id).updateChildValues(BookingViewController.kardexDict)
     print("save kardexDict")
 }

我希望得到以下结果

" 1:获取患者名称" ->"在getID中运行" ->" 2:获取护士名称" ->"在getid中运行" ->"保存kardexdict"

但我得到了
" 1:获取患者名称" ->" 2:获取护士名称" ->"保存kardexdict"

和kardexdict中的数据是不正确的,因为数据未从function getID((获得我该怎么做才能遵循我期望的订单。

您以错误的方式使用firebase:

  • observeSingleEvent异步运行,因此事件的顺序将是:"在getid中运行" ->" 1:获取患者名称"
  • updateChildValues通常会在任何observeSingleEvent完成之前调用

因此,您首先在拿到病人或护士名称之前将空的(?(kardexDict写信给Firebase。

另外,请注意completion闭合在主线程中不运行。因此,您可能会观察到一些不可预测的并发问题/种族条件。您要做的就是等待所有observeSingleEvent完成,然后再写数据。


更新

因此,您的想法的或多或少或多或少地转移可以看起来像这样(可能不完全编译,因为我没有您的环境运行(:

func getId(path:String, value:String?, completion: @escaping (String?) -> Void) {
    let ref = Database.database().reference(withPath: path).queryOrdered(byChild: "name").queryEqual(toValue: value)
    ref.observeSingleEvent(of: .childAdded, with: { snapshot in
        print("running in getId")
        completion(snapshot.key)                
    }) { (error) in
        print(error.localizedDescription)
    }
}
@objc func onTapConfirmed(){
    let patientName = self.kardex?.patient?.name
    let nurseName = BookingTreatmentListController.nurseName
    self.getId(path: "patients", value: patientName) { snapshotKey in
        print("1:got patient")
        let patient = snapshotKey as AnyObject?
        self.getId(path: "nurses", value: nurseName) { snapshotKey in
            print("2:got nurse")
            let nurse = snapshotKey as AnyObject?
            DispatchQueue.Main.async {
                print("save kardexDict (in main thread!")
                BookingViewController.kardexDict["patient"] = patient
                BookingViewController.kardexDict["nurses"] = nurse
                let kardexes = Database.database().reference().child("kardexes")
                kardexes.child(BookingViewController.newKardex.id).updateChildValues(BookingViewController.kardexDict)
            }
        }
    }
}

尽管如此,可能不是,因为涉及两个独立的网络呼叫(首先是患者,然后是护士(。也许您最好使用observe代替observeSingleEvent

最新更新