0

我试图弄清楚如何仅在 Firebase 中的 observeSingleEvent 完成工作后触发操作。

背后的原因是我需要做以下操作:

  • 根据用户的一项输入,我需要从数据库中获取一些数据
  • 当这些数据完全下载后,我需要对它们进行一点处理并用于检索要显示给用户的其他数据

目前我正在使用这段代码:

    let listOfTags = [String]()
    var outputArray = [String]()

    if listOfTags.count != 0 {
        for tag in listOfTags {

            ref.child("tags").child(tag).observeSingleEvent(of: .value, with: { (snapshot) in

                if let temp = snapshot.children.allObjects as? [FIRDataSnapshot] {
                    for elem in temp {
                        outputArray.append(elem.key)
                    }
                }

                // ...
            }) { (error) in
                print(error.localizedDescription)
            }
        }

        // HERE I WANT TO DO AN ACTION "ONLY" AFTER THE FOR LOOP IS
        // COMPLETED AND THE "outputArray" IS FILLED WITH ALL VALUES
        doSomethingHere()

    }

但是我注意到当 outputArray 仍然是 EMPTY 时,函数 doSomethingHere() 会立即执行!所以它什么也不做。

那么我的问题是,如何构建程序以便在下载过程完成后执行此功能?也许observeSingleEvent 不是要使用的正确Firebase 方法?对于这种特定情况,我不想观察到任何变化(因为这个列表不会经常变化),我只需要下载数据并稍后对这些数据执行其他操作..

4

1 回答 1

4

Firebase 是异步的,因此要使代码按定义的顺序执行,您需要“等待”firebase 返回数据。

Firebase 函数的闭包就是这样做的——闭包中的代码在数据(快照)有效时执行。

将 doSomethingHere() 移动到 Firebase 闭包内,它将以正确的顺序执行 - 在这种情况下

if listOfTags.count != 0 {
    for tag in listOfTags {

        ref.child("tags").child(tag).observeSingleEvent(of: .value, with: { (snapshot) in

            if let temp = snapshot.children.allObjects as? [FIRDataSnapshot] {
                for elem in temp {
                    outputArray.append(elem.key)
                }
                doSomethingHere() //array is populated at this point
            }
        })
    }
}

请注意,您也可以删除此

if listOfTags.count != 0

如果 listOfTags 为 0,则不会执行 for 循环。

于 2017-03-26T13:08:19.437 回答