Swift Firebase:遍历数据,只有在旧循环完成加载后才开始新循环
Swift Firebase: loop through data and only start the new loop if the old one has finished loading
我遇到了麻烦,因为我正在以用户的形式加载大量数据条目(大约 1000 个)。现在,我获取用户的用户 ID,并将他们的行和用户数据插入到我的 table 视图中。问题是,目前我的应用程序一直在等待,直到它完成所有存在的用户 ID,然后才开始插入它们。这是代码:
let group = DispatchGroup()
for each in userIDs {
check(identifier: "DispatchGroup", text: "\(each) started")
Database.database().reference().child("user-data").child(each).observeSingleEvent(of: .value, with: { (snap) in
if let data = snap.value as? [String:AnyObject] {
if let name = data["name"] as? String, let urlToImage = data["imagePath"] as? String, let status = data["status"] as? String {
let newUser = User()
newUser.name = name
newUser.imagePath = urlToImage
newUser.status = status
self.usersTableView.append()
if let index = self.usersTableView.index(of: newUser) {
self.tableView.insertItems(at: [IndexPath(row: index, section: 0)])
check(identifier: "FeedLoad", text: "inserting user \(newUser.userName) at timestamp \(Date().timeIntervalSince1970)")
}
check(identifier: "DispatchGroup", text: "\(each) ended")
print("Reloading table view at \(Date().timeIntervalSince1970)")
group.leave()
}
}
})
}
现在,打印出来的是:
调度组:xRDlUIBAsqeI13ykVsEx9P7okph2 已启动
调度组:dFVZAQmPb0TRRD94sPR32FbYWyk1 已启动
调度组:xRDlUIBAsqeI13ykVsEx9P7okph2 结束
调度组:dFVZAQmPb0TRRD94sPR32FbYWyk1 结束
但我想让它说:
调度组:xRDlUIBAsqeI13ykVsEx9P7okph2 已启动
调度组:xRDlUIBAsqeI13ykVsEx9P7okph2 结束
调度组:dFVZAQmPb0TRRD94sPR32FbYWyk1 已启动
调度组:dFVZAQmPb0TRRD94sPR32FbYWyk1 结束
如何实现?
有几种方法可以实现这一点。 Firebase 没有针对此类内容的完成处理程序,但您可以做的是,如果您在 for 循环中有少量 ID,只需像这样嵌套它:
Database.database().reference().child("user-data").child(id1).observeSingleEvent(of: .value, with: { (snap) in
Database.database().reference().child("user-data").child(id2).observeSingleEvent(of: .value, with: { (snap) in
Database.database().reference().child("user-data").child(id3).observeSingleEvent(of: .value, with: { (snap) in
}
}
}
但是如果数据可能会有所不同,实现这一点的另一种方法是存储一个 id 字典和 Bool 来检查是否完成。
var ids = ["id1" : false, "id2" : false, "id3" : false]
func getNext() {
// If all ids == true { return }
// if not, get the next id
Database.database().reference().child("user-data").child(id1).observeSingleEvent(of: .value, with: { (snap) in
ids["id1"] = true
getNext()
}
}
也不要每次请求都调用 Database.Database().reference()
。而是将其存储为变量。检查此以获取更多信息:Firebase best practices
我遇到了麻烦,因为我正在以用户的形式加载大量数据条目(大约 1000 个)。现在,我获取用户的用户 ID,并将他们的行和用户数据插入到我的 table 视图中。问题是,目前我的应用程序一直在等待,直到它完成所有存在的用户 ID,然后才开始插入它们。这是代码:
let group = DispatchGroup()
for each in userIDs {
check(identifier: "DispatchGroup", text: "\(each) started")
Database.database().reference().child("user-data").child(each).observeSingleEvent(of: .value, with: { (snap) in
if let data = snap.value as? [String:AnyObject] {
if let name = data["name"] as? String, let urlToImage = data["imagePath"] as? String, let status = data["status"] as? String {
let newUser = User()
newUser.name = name
newUser.imagePath = urlToImage
newUser.status = status
self.usersTableView.append()
if let index = self.usersTableView.index(of: newUser) {
self.tableView.insertItems(at: [IndexPath(row: index, section: 0)])
check(identifier: "FeedLoad", text: "inserting user \(newUser.userName) at timestamp \(Date().timeIntervalSince1970)")
}
check(identifier: "DispatchGroup", text: "\(each) ended")
print("Reloading table view at \(Date().timeIntervalSince1970)")
group.leave()
}
}
})
}
现在,打印出来的是:
调度组:xRDlUIBAsqeI13ykVsEx9P7okph2 已启动
调度组:dFVZAQmPb0TRRD94sPR32FbYWyk1 已启动
调度组:xRDlUIBAsqeI13ykVsEx9P7okph2 结束
调度组:dFVZAQmPb0TRRD94sPR32FbYWyk1 结束
但我想让它说:
调度组:xRDlUIBAsqeI13ykVsEx9P7okph2 已启动
调度组:xRDlUIBAsqeI13ykVsEx9P7okph2 结束
调度组:dFVZAQmPb0TRRD94sPR32FbYWyk1 已启动
调度组:dFVZAQmPb0TRRD94sPR32FbYWyk1 结束
如何实现?
有几种方法可以实现这一点。 Firebase 没有针对此类内容的完成处理程序,但您可以做的是,如果您在 for 循环中有少量 ID,只需像这样嵌套它:
Database.database().reference().child("user-data").child(id1).observeSingleEvent(of: .value, with: { (snap) in
Database.database().reference().child("user-data").child(id2).observeSingleEvent(of: .value, with: { (snap) in
Database.database().reference().child("user-data").child(id3).observeSingleEvent(of: .value, with: { (snap) in
}
}
}
但是如果数据可能会有所不同,实现这一点的另一种方法是存储一个 id 字典和 Bool 来检查是否完成。
var ids = ["id1" : false, "id2" : false, "id3" : false]
func getNext() {
// If all ids == true { return }
// if not, get the next id
Database.database().reference().child("user-data").child(id1).observeSingleEvent(of: .value, with: { (snap) in
ids["id1"] = true
getNext()
}
}
也不要每次请求都调用 Database.Database().reference()
。而是将其存储为变量。检查此以获取更多信息:Firebase best practices