Firebase在调用下一个方法之前未完成

时间:2019-04-26 13:31:01

标签: swift firebase firebase-realtime-database

我正在通过以下方式调用Firebase数据库:

    let myRef1 = Database.database().reference(withPath: "/tests/\ . 
     (myTest)")
    print(myTest)
    myRef1.observe(.value, with: {
        snapshot in
        print(snapshot)
        var newItems: [qItem] = []
        for item in snapshot.children {
            let mItem = qItem(snapshot: item as! DataSnapshot)
            newItems.append(mItem)
            print(newItems)
        }
        self.myArray = newItems.shuffled()
        print(self.myArray)
    })

    loadNext()
    ...

但是,在执行下一个方法调用之前,它永远不会完成完成处理程序,这取决于此操作的结果。

试图将其设置为单独的方法,等等,但是似乎没有任何效果。

2 个答案:

答案 0 :(得分:1)

您需要在loadNext()内添加方法observe,以便在检索数据后可以调用它。当您检索数据时,它是异步发生的,这意味着编译器不会等到检索到所有数据后,才会先调用方法loadNext(),然后在检索完数据后将执行print(newItems),因此您需要执行以下操作:

    myRef1.observe(.value, with: {
    snapshot in
    print(snapshot)
    var newItems: [qItem] = []
    for item in snapshot.children {
        let mItem = qItem(snapshot: item as! DataSnapshot)
        newItems.append(mItem)
        print(newItems)
        loadNext()
    }
    self.myArray = newItems.shuffled()
    print(self.myArray)
})

答案 1 :(得分:0)

Firebase数据是异步处理的。道格·史蒂文森(Doug Stevenson)写了一篇很棒的blog,说明了为什么这样做以及对开发人员意味着什么。我还写了一个blog,其中展示了如何在函数中使用闭包来处理异步数据。虽然您可以肯定地从loadNext()闭包内部调用observe,但您可能会发现在同一函数内部最终会产生很长的闭包序列。我在博客文章中对此进行了更多介绍。在您的特定情况下,您可以执行以下操作:

func getArray(completion: @escaping ([qtItem]) -> Void) {
  let myRef1 = Database.database().reference(withPath: "/tests/\ . 
     (myTest)")
  print(myTest)
  myRef1.observe(.value, with: {
      snapshot in
      print(snapshot)
      var newItems: [qItem] = []
      for item in snapshot.children {
          let mItem = qItem(snapshot: item as! DataSnapshot)
          newItems.append(mItem)
          print(newItems)
      }
      self.myArray = newItems.shuffled()
      print(self.myArray)
      completion(self.myArray)
  })
}

然后,当您调用getArray()时,可以在闭包内部处理数据:

getArray() { newItems in
  // do something with newItems, like pass to `loadNext()` if needed
  self.loadNext()
}