swift - GeoFire observeReady 在 Swift 中过早执行
问题描述
在以下函数中,我正在执行初始 geofire 搜索查询,并希望处理找到的所有键,将它们附加到数组并将整个数组发回。
问题是observeReady
代码块执行得太早了,因此发送了一个空数组(即使在范围内找到了键,在第一次加载时也没有显示)。
我知道observeSingleEvent
调用是asynchronous
并且可能导致这种行为,所以我的问题是,我该如何管理这个并确保handler
在块内执行调用之前处理密钥observeReady
?
func fetchInitialNearbyVenues(deviceLocation: CLLocation, radius: Double, handler: @escaping ([Venue]) -> ()) {
self.venuesArray.removeAll()
var savedByUsers = [String : String]()
let query = self.GEOFIRE_VENUES_LOC.query(at: deviceLocation, withRadius: radius)
query.observe(.keyEntered) { (key: String!, venueLocation: CLLocation!) in
self.REF_VENUES.child(key).observeSingleEvent(of: .value, with: { (snapshot) in
//process snapshot create and append Venue object to array
//...
//...
self.venuesArray.append(venue) //append Venue to array
})//end observeSingleEvent
}//end geofire query observe
query.observeReady {
handler(self.venuesArray) //PROBLEM: This gets executed prematurely thus sending an empty array via handler
}
}//end func
解决方案
你看到的是预期的行为。observeReady
保证在所有对应的调用后触发observe(.keyEntered)
。您可以使用一些简单的日志记录语句来验证这一点:
query.observe(.keyEntered) { (key: String!, venueLocation: CLLocation!) in
print(".keyEntered")
}
query.observeReady {
print(".observeReady")
}
当你运行它时,它将打印:
.keyEntered
.keyEntered
...
.observeReady
这符合 API 的工作方式。但是在.keyEntered
您正在从 Firebase 加载其他数据时,这是异步发生的。并且这些调用可能在触发后确实完成。.observeReady
因此,您需要自己实现必要的同步。检测是否已加载所有附加数据的一种简单方法是对仍需要加载数据的所有键进行计数。所以你+1
每次添加一个密钥,-1
每次加载场地数据时:
let venuesToLoadCount = 0
query.observe(.keyEntered) { (key: String!, venueLocation: CLLocation!) in
venuesToLoadCount = venuesToLoadCount + 1
self.REF_VENUES.child(key).observeSingleEvent(of: .value, with: { (snapshot) in
venuesToLoadCount = venuesToLoadCount - 1
if venuesToLoadCount == 0 {
print("All done")
}
}
}
query.observeReady {
if venuesToLoadCount == 0 {
print("All done")
}
}
推荐阅读
- python - 尝试使用 map 或 list comprehensions 展平列表列表时获得额外的 Nones 行,为什么?
- python - 如何将用户输入的值更改为对应的字典值
- ruby - 如何暂停音乐曲目而不跳过它们
- python - Python Pandas 将日期字符串转换为日期时间
- roblox - 我将如何在 Roblox 中制作 BodyGiro 以确保零件是直立的?
- python - 错误:尝试在 CentOS 7 上安装 pgAdmin 4 Web 界面
- rust - 使用方法调用结果时的多个可变借用
- docker - 无法从 docker 容器连接到 redis 集群
- amazon-web-services - 通过 AWS SES 接收电子邮件时使用哪个电子邮件地址
- mysql - 不同数据的sql连接问题