嵌套for循环中的多个异步请求

时间:2018-03-19 00:55:50

标签: swift firebase asynchronous firebase-realtime-database

我试图从我的数据库中获取数据,并在获取一段数据后,使用该数据来查找新的数据。

最后,我可以将它们拼凑在一起并返回派生数据。我不确定这是解决这个问题的最佳方法,但现在就是我所处的位置。

我的问题是每次调用数据库(Firebase)都是异步的,因此我需要以某种方式等待异步完成,然后继续。

我看了调度组,看看我到目前为止所做的事情:

 let taskGroup = DispatchGroup()

    for buildingKey in building.allKeys
    {
      var aprt = NSDictionary()

      taskGroup.enter()
         // ASYNC REQUEST
      getAbodesWithUID(UID: buildingKey as! String, callback: { (success, abodes) in
        aprt = abodes
        taskGroup.leave()
      })

      taskGroup.enter()
      for key in aprt.allKeys
      {
        // ASYNC REQUEST
        getTenantsWithAprt(UID: key as! String, callback: { (success, user) in
          for userKey in user.allKeys
          {
            let dict = NSMutableDictionary()
            dict.setValue(((building[buildingKey] as? NSDictionary)?["Address"] as? NSDictionary)?.allKeys[0] as? String, forKey: "Building")
            dict.setValue((user[userKey] as? NSDictionary)?["Aprt"], forKey: "Number")
            dict.setValue((user[userKey] as? NSDictionary)?["Name"], forKey: "Name")
            dict.setValue(userKey, forKey: "UID")
            dict.setValue((user[userKey] as? NSDictionary)?["PhoneNumber"], forKey: "Phone")
            apartments.append(dict)
          }
          taskGroup.leave()
        })
      }
    }

    taskGroup.notify(queue: DispatchQueue.main, execute: {
      print("DONE")
      callback(true, apartments)
    })

我似乎无法正确回调

2 个答案:

答案 0 :(得分:1)

首先,你应该在aprt.allKeys的回调中迭代getAbodesWithUID,否则,当for循环执行时aprt将是一个空字典。

其次,for循环之上的taskGroup.enter()调用应该在for循环中,因为需要为每个键调用一次。它应放在当前// ASYNC REQUEST评论的位置。

答案 1 :(得分:0)

这正是“承诺”的目的。它们通过第三方加载项在Swift中提供。一种流行的方法是将所有读取/获取推送到数组中。然后你promise.all(yourArray)返回结果/值的数组,然后迭代到每个结果/值。

来自this other answer

  

您可以查看哪些内容可能提供您所需要的内容   here

     

使用循环将promises放入数组中,然后执行某些操作   像这样:

when(fulfilled: promiseArray).then { results in
    // Do something
}.catch { error in
    // Handle error
}