且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用Firestore DB,当满足特定条件时,如何突破快照侦听器内部的for循环?

更新时间:2023-01-14 11:48:49

问题中代码的第一个问题是Firestore是异步的.

The first issue with the code in the question is that Firestore is asynchronous.

闭包之后的任何代码都将在闭包中的代码之前执行.从服务器检索数据需要花费时间,并且检索到数据后,闭包中的代码将运行.

Any code following a closure will execute before the code in the closure. It takes time for data to be retrieved from the server and the code within the closure runs after that data is retrieved.

所以这行

if containsDay == true {

需要移动.

弗兰克的答案很好,但另一种解决方案是在转义时使用转义符

Frank's answer is excellent but another solution is to use escaping along with a break

假设我们要检索用户的uid-在这种情况下,我们遍历users节点以查找Bob.

Suppose we want to retrieve the uid of a user - in this case we iterate over the users node to look for Bob.

users
   uid_0
      name: "Frank"
   uid_1
      name: "Bill"
   uid_2
      name: "Bob"

这是我们调用函数的代码

Here's the code we call our function with

self.lookForBobsUid(completion: { bobsUid in
    print("Bob's uid is: \(bobsUid)")
})

然后读取所有用户的函数,对其进行迭代,然后当我们找到Bob时,返回Bobs uid并退出循环.

and then the function that reads in all of the users, iterates over them and then when we find Bob, return Bobs uid and break out of the loop.

func lookForBobsUid(completion: @escaping ( (String) -> Void ) ) {
    let usersCollection = self.db.collection("users")
    usersCollection.getDocuments(completion: { snapshot, error in
        if let err = error {
            print(err.localizedDescription)
            return
        }

        guard let documents = snapshot?.documents else { return }

        for doc in documents {
            let uid = doc.documentID
            let name = doc.get("name") as? String ?? "No Name"
            print("checking name: \(name)")
            if name == "Bob" {
                print("  found Bob, leaving loop")
                completion(uid)
                break
            }
        }
    })

    print("note this line will print before any users are iterated over")
}

请注意,我在代码末尾添加了一行以演示异步调用的性质.

Note that I added a line at the end of the code to demonstrate the nature of asynchronous calls.

通常所说的所有这些,通常都可以避免遍历集合以寻找某些东西.

All of that being said, generally speaking, iterating over collections to look for something can usually be avoided.

看来您正在寻找解决办法

It appears you're looking for whatever this resolves to

self.daysOfWeek[self.picker.selectedRow(inComponent: 0)]

如果是这样,建议您查询self.colRef以获取该项目,而不是迭代查找它;这样会更快,并使用更少的资源,并且具有可伸缩性-如果要遍历100,000个节点,该怎么办!

If so, it would be advisable to query self.colRef for that item instead of iterating to find it; that will be way faster and use less resources and will also be scalable - what if there were 100,000 nodes to iterate over!