简体   繁体   English

仅在设置了数据后如何调用完成处理程序?

[英]How do I call the completion handler only once the data has been set?

The function seen below appears to deliver the orderId via completion handler before the data has been set in firebase, which causes a backend function that uses the orderId to retrieve associated data from Firestore to fail. 在Firebase中设置数据之前,下面看到的函数似乎是通过完成处理程序传递orderId的,这会导致使用orderId从Firestore检索关联数据的后端函数失败。 It's possible that the backend function is failing for other reasons, but it's probably because the function has not finished setting the data to firestore when it delivers the orderId. 后端函数可能由于其他原因而失败,但这可能是因为该函数在传递orderId时尚未完成将数据设置为firestore的操作。 How do I make it so my function delivers the orderId only once the data has been set? 我该如何做才能使我的函数仅在设置数据后才传递orderId?

public func uploadTransactionData(_ menuItems: [MenuItem], tip: Int, tax: Int, rewardAmountApplied: Int, totalPaidFromCredit: Int, discountAmount: Int, subTotal: Int, balanceId: String, locationId: String, completion: @escaping ((String?) -> ())) {
    guard let userId = Auth.auth().currentUser?.uid else { completion(nil); return }
    let utilitiesManager = UtilitiesManager()
    let timestamp = utilitiesManager.timestamp()
    var listOfItems = [Any]()
    for item in menuItems {
        do {
            let jsonData = try JSONEncoder().encode(item)
            let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: [])
            listOfItems.append(jsonObject)
        }
        catch let err {
            print("$-- error uploading transaction data \(err)")
            completion(nil)
            return
        }
    }
    let orderRef = Firestore.firestore().collection("order").document()
    let orderId = orderRef.documentID
    let totalPrice = subTotal + tax + tip + discountAmount
    let params: [String: Any] = ["date": timestamp,
                                "total_amount": totalPrice,
                                "tip_amount": tip,
                                "tax_amount":tax,
                                "discount_amount": discountAmount,
                                "reward_amount": rewardAmountApplied,
                                "balance_amount": totalPaidFromCredit,
                                "balance_id": balanceId,
                                "subtotal": subTotal,
                                "account_id": userId,
                                "location_id": locationId,
                                "status": "PENDING",
                                "notes": "",
                                "line_items": listOfItems
    ]
    orderRef.setData(params)
    { err in
        if let e = err {
            print("$-- error uploading transaction data \(e)")
            completion(nil)
        } else {
            completion(nil)
        }
    }
    completion(orderId)
}

setData is asynchronous and returns immediately, before the database generates any results. setData是异步的,并在数据库生成任何结果之前立即返回。 You're calling completion() at the end of your function unconditionally, before the results are complete. 在结果完成之前,您无条件地在函数末尾调用了completion()。 Perhaps you meant to say something like this instead: 也许您是想这样说:

orderRef.setData(params)
{ err in
    if let e = err {
        print("$-- error uploading transaction data \(e)")
        completion(nil)
    } else {
        // Change this line to yield the order id to the callback on success
        completion(orderId)
    }
}
// Remove this line that always calls the completion before the result
// completion(orderId)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM