【问题标题】:how to use a completion handler to await the completion of a firestore request如何使用完成处理程序来等待 Firestore 请求的完成
【发布时间】:2017-12-19 13:09:23
【问题描述】:

我正在慢慢了解完成处理程序。 如果我有一个firestore查询,如果我想使用完成处理程序,我必须在firestore查询完成时使用completion()。

但它设置的功能仍然让我感到困惑。

如果这是一个以闭包为参数的函数定义:

  func doSomethingAsync(completion: () -> ()) {
  }

我不太明白如何从上面的 func 定义中走出来,并将其实现为真正的东西,例如 firestore 查询和请求。

 query.getDocuments(){ (querySnapshot, err) in

                if let err = err
                {
                    print("Error getting documents: \(err)")
                }
                else
                {
                    if(querySnapshot?.isEmpty)!
                    {


                        print("there's no document")
                        completion()


                    }
                    else
                    {
                        for document in querySnapshot!.documents
                        {

                            completion()

                        }
                    }
                }

            }

谢谢。

更新

所以对于我的例子,我可以做类似的事情

func getFirestoreData(userID: String, completion @escaping() -> ()){

//firestore code:

query.getDocuments(){ (querySnapshot, err) in

                    if let err = err
                    {
                        print("executed first")
                        completion()
                    }
                    else
                  .......
                    print("executed first")
                    completion()

       }
}

调用我正在执行的函数:

getFirestoreData(userID: theUserID) {

            print("executes second")

        }

print("executes third") after function execution.

我想要发生的是编程在继续执行之前等待完成()。

但是“第三次执行”首先发生,然后是“先执行”,然后是“第二次执行”。

谢谢

【问题讨论】:

    标签: swift google-cloud-firestore


    【解决方案1】:

    这里是完整的例子(使用 API 调用) 请注意:状态变量只是找出服务器响应的关键 (0:来自服务器的错误,1:成功,-1:我的代码有问题)

     func logout(handlerBack: @escaping (_ error: Error?, _ status:Int?, _ error_message:String?)->())
    {
    
        Alamofire.request(url, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil)
            .responseJSON { respons in
                switch respons.result {
                case .failure(let theError):
                    handlerBack(theError, 0, nil)
    
                case .success(let data):
                    let json_data = JSON(data)
    
                    /// if couldn't fetch data
                    guard let status = json_data["status"].int else {
                        handlerBack(nil,-1, "can't find status")
                        return
                    }
    
                    /// if statuse == 0
                        guard status == 1 else {
                            handlerBack (nil, 0 , json_data["errorDetails"].string)
                            return
                        }
    
                    // that's means everything fine :)
                        handlerBack(nil, 1 , nil)
                    }
            }
        }
    

    这是实现它的方法:

            // call func 
      self.logout { (error:error, status:Int, error_message:String) in
                // if status not 1, figure out the error 
            guard status == 1 else {
                // try to find error from server
                guard let error_message = error_message else {
                // else error something else 
                    print ("Error at :: \(#function)")
                    // don't do anything ..just return 
                    return
                }
                self.showMessageToUser(title: error_message, message: "", ch: {})
                return
            }
                       // this part do what ever you want, means every thing allright 
        }
    

    更新: 您正在寻找等待单元执行“第一”和“第二”的东西

    在这种情况下使用DispatchGroup() 这是示例:

                var _dispatch_group = DispatchGroup()
    
            getFirestoreData(userID: theUserID) {
    
                _dispatch_group.enter()
                print("executes second")
    
    
                _dispatch_group.leave()
    
            }
    
            _dispatch_group.notify(queue: .main) {
            print("executes third")
            }
    

    输出是:

    executes First
    executes Second
    executes Third
    

    【讨论】:

    • 我能澄清一下吗?在注销的函数定义中是 (_error:Error?, _status:Int?, _error_message:String?)->() 闭包?所以你要传入三个参数并返回 void?然后alamofire请求就是api调用。当它成功结束时,您是否正在调用 handlerBack?我不太明白的一点是函数执行 self.logout - self.logout 需要 { (error:error, status:Int, error_message:String) 但我仍然不明白为什么你需要传入三个参数。谢谢(我已经更新了我原来的帖子)
    • 我收到了您的请求,在这种情况下,您正在寻找 dispatchGroup,我会更新我的答案
    • @Mike 对你有帮助吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    相关资源
    最近更新 更多