ios - 确保 Firebase 中的异步操作已完成

标签 ios swift asynchronous firebase

我需要快速对 Firebase 运行并发查询。如何确保在我的应用程序中允许开始另一个操作之前循环查询已完成?

例如,第一个查询很简单,只是提取数据。但第二个,迭代一个数组,在我的 firebase 数据库中查找某个节点,循环遍历数组 self.contacts:

 // First check if friend, and remove/add to
            friendsURL.observeSingleEventOfType(.Value, withBlock: { snapshot in

                for oneSnapshot in snapshot.children {

                    for oneContact in contactsArray {

                        for oneContactPhoneNum in oneContact.phoneNumbers {

                            let phoneNumber = oneContactPhoneNum.value as! CNPhoneNumber

                            contactNumber = phoneNumber.stringValue

                            // Clean the number
                            let stringArray = contactNumber!.componentsSeparatedByCharactersInSet(
                                NSCharacterSet.decimalDigitCharacterSet().invertedSet)
                            let newString = "1" + stringArray.joinWithSeparator("")

                            let firebaseFriendNumber = oneSnapshot.value["phoneNumber"] as! String

                            if newString == firebaseFriendNumber {

                                self.friends.append(Friend(userName: oneSnapshot.value["userName"] as! String,phoneNumber: firebaseFriendNumber, status: 2, name: oneContact.givenName, userID: oneSnapshot.key))

                                // Remove that contact
                                self.contacts.removeObject(oneContact)
                            }
                        }
                    }
                }

                // Now do the users search:
                for oneContact in self.contacts {
                    for oneContactNumer in oneContact.phoneNumbers {

                        let phoneNumber = oneContactNumer.value as! CNPhoneNumber

                        contactNumber = phoneNumber.stringValue

                        let stringArray = contactNumber!.componentsSeparatedByCharactersInSet(
                            NSCharacterSet.decimalDigitCharacterSet().invertedSet)
                        let newString = "1" + stringArray.joinWithSeparator("")

                        let usersURL: Firebase! = Firebase(url: firebaseMainURL + "presentUserIDUserNameByPhoneNumber/" + newString)

                        // Check db:

                        usersURL.observeSingleEventOfType(.Value, withBlock: { snapshot in

                            if snapshot.childrenCount > 1 {

                                // They are users (but not your friends):
                                self.friends.append(Friend(userName: snapshot.value["userName"] as! String, phoneNumber: snapshot.key, status: 1, name: "test", userID: snapshot.value["userID"] as! String))

                                let userName = snapshot.value["userName"] as! String

                                print("Friends name: " + userName)

                                // Remove that contact
                                self.contacts.removeObject(oneContact)

                            }

                        })

                    }

                }

            })

在允许应用程序中发生其他操作之前,如何测试和检查 usersURL 上的第二个操作何时完成?

最佳答案

发出异步函数完成信号的一种方法是使用完成处理程序。您已经在 Firebase API 中使用了完成处理程序,并且系统框架中有很多 API,因此我不再进一步解释。

采用这种方法,将您的代码包装到一个函数中,例如带有完成处理程序的 updateContacts 。通常,异步函数返回计算的错误。在某些情况下,它只是成功或失败 - 不返回值。您可以在完成处理程序的签名中表达这一点。您的函数 updateContacts 可能不会计算值,但它可能会失败或成功。然后,您可以使用一个可选错误:如果它为nil,则任务成功,否则包含发生的错误。

当您的基础任务完成后,使用结果调用完成处理程序。

注意:必须确保完成处理程序最终会被调用!

func updateContacts(completion: (ErrorType?)-> ()) {
    friendsURL.observeSingleEventOfType(.Value, withBlock: { snapshot in
        ...
            ...
                ...
                    usersURL.observeSingleEventOfType(.Value, withBlock: { snapshot in
                        ...
                        let error = // nil or an error
                        completion(error)
                       return
                     }
        completion(nil)
    }    
}

现在,当您有一组异步子任务时,将并行调用这些子任务,并且您希望在所有子任务完成时发出 updateContacts 完成的信号 - 您可以利用调度组:

let group = dispatch_group_create()
var error: ErrorType?
contactNumbers.forEach { number in
    dispatch_group_enter(group)
    queryAsync(number) { (result, error) in
        if let error = error {
            // handle error
        } else {
            ...
        }             
        dispatch_group_leave(group)
    }
}
dispatch_group_notify(group, queue) {
    // call the completion handler of your function `updateContacts`:
    completion(error)
}

关于ios - 确保 Firebase 中的异步操作已完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37150743/

相关文章:

ios - 单击后无法设置 UITableViewCell 中的 UIButton 图像

javascript - 异步等待 promise 所有与存储在变量中

ios - iOS 应用程序的 iTunes Connect 验证时出现无效代码签名权利错误

ios - 从 UITableViewCell 中的 UITextField 获取数据

xcode - 如何将 iPad View 选项添加到 Xcode 预览?

asynchronous - Future.error 和 dart Future 中的 throw 有什么区别?

c# - ConfigureAwait(false) 仍然死锁

javascript - TypeError: Undefined 不是一个函数。 iOS Safari 评估功能。 CoffeeScript

ios - 使用 Sinch 或 Twilio 创建随机呼出和呼入调用?

swift - AdMob 显示测试广告但不显示真实广告 Swift/SwiftUI