使用嵌套的异步Firebase调用SwiftUI [英] Working with nested async Firebase calls SwiftUI

查看:82
本文介绍了使用嵌套的异步Firebase调用SwiftUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对异步函数还比较陌生,我知道firebase的getDocument和getDocuments调用是异步的.在继续执行代码中的工作之前,我希望这两个调用均能完成.我一直在尝试通过调度组来实现这一点,但是到目前为止还没有成功.我有如下代码:

I am relatively new to async functions and I understand that the firebase getDocument and getDocuments calls are async. I would like both of these calls to finish before I move on to what I was doing in the code. I've been trying to implement this with dispatch groups, but have been unsuccessful thus far. I have code like the following:

                
                let myGroup = DispatchGroup()
                self.errorMessage = ""
                let usersRef = self.db.collection("Users").document("Users").collection("Users")
                if self.test == false {
                    self.errorMessage = "test failed"
                } else{
                    //first async call
                    myGroup.enter()
                    usersRef.getDocuments {(snap, err) in
                        //basically getting every username
                        for document in snap!.documents{
                            print("loop")
                            let user = document["username"] as! String
                            let userRef = usersRef.document(user)
                            //second async call
                            userRef.getDocument { (snapshot, err) in
                                if err != nil {
                                    print(err)
                                } else {
                                    let self.error = snapshot!["error"] as! Bool
                                    if self.error == true{
                                        self.errorMessage = "error"
                                        print("error")
                                    }
                                    print("what3")
                                }
                                print("what2")
                            }
                            print("what1")
                        }
                        myGroup.leave()
                        print("what4")
                    }
                    //RIGHT HERE I WANT TO CONTINUE WHAT I WAS DOING BEFORE
                    myGroup.notify(queue: DispatchQueue.global(qos: .background)) {
                        print("HERE I SHOULD BE DONE")
                    }
                    
                    print("what5")
                }

但是,这会产生类似以下内容:

However, this produces something like:

what5
loop
what1
loop
what1
loop
what1
loop
what1
loop
what1
loop
what1
what4
HERE I SHOULD BE DONE
error
what3
what2
error
what3
what2
what3
what2
error
what3
what2
what3
what2
error
what3
what2

因此,似乎第一个异步调用已完成,但是第二个继续执行.我想等待第二秒结束,然后再继续.

So it seems like the FIRST async call is finishing, but then the second continues executing. I'd like to wait for the second to finish before continuing.

任何有关如何修改此代码的建议将不胜感激. 谢谢.

Any advice on how to modify this code would be greatly appreciated. Thanks.

推荐答案

进行第二次getDocuments调用时,您需要再次重新输入该组.因为它也将是异步的.这样的事情应该可以解决问题:

You need to re-enter a the group again when doing the second getDocuments call. As it will also be asynchron. Something like this should do the trick:

let myGroup = DispatchGroup()
        //Enter first time for first async call
         myGroup.enter()
         self.errorMessage = ""
         let usersRef = self.db.collection("Users").document("Users").collection("Users")
         if self.test == false {
             self.errorMessage = "test failed"
         } else{
            usersRef.getDocuments {(snap, err) in //Starting first async call
                
                for document in snap!.documents{
                    print("loop")
                    let user = document["username"] as! String
                    let userRef = usersRef.document(user)
                    
                    //Enter second time for second async call
                    myGroup.enter()
                    userRef.getDocument { (snapshot, err) in // starting second async call
                        if err != nil {
                            print(err)
                        } else {
                            let self.error = snapshot!["error"] as! Bool
                            if self.error == true{
                                self.errorMessage = "error"
                                print("error")
                            }
                            print("what3")
                        }
                        print("what2")
                        //Leave second async call
                        myGroup.leave()
                    }
                    print("what1")
                }
                //Leave first async call
                myGroup.leave()
                print("what4")
             }

             myGroup.notify(queue: DispatchQueue.global(qos: .background)) {
                 print("HERE I SHOULD BE DONE")
             }
             
             print("what5")
         }
        
    }

推荐:使用DispatchGroup/Asynchron调用时,请尝试将它们分开.例如为每个调用使用一个函数,因为它很快就会变得非常混乱.将它们分开,然后将它们组合为一种方法,还可以更轻松地修改和/或发现错误.

Recommendation: When using DispatchGroup/ Asynchron calls try to divide them. For e.g. use a function for each call as it can get really quickly really messy. Having them separated and then combining them in one method makes it also easier to modify and or find errors.

这篇关于使用嵌套的异步Firebase调用SwiftUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆