确保异步操作已经完成了火力地堡 [英] Ensuring Async Action Has Completed in Firebase

查看:204
本文介绍了确保异步操作已经完成了火力地堡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在运行迅速并发查询到火力地堡。我怎样才能确保允许另一个动作之前,我的应用程序启动一个环形查询已完成?

I need to run concurrent queries to Firebase in swift. How can I ensure that a looped query has finished before another action is allowed to start in my app?

例如,第一个查询是一个简单的,简单地提取数据。但第二,通过阵列迭代寻找我的火力点数据库中的某个节点,通过数组 self.contacts 循环:

For example, the first query is a straightforward, and simply pulls data. but the second, iterates through an array looking for a certain node in my firebase database, looping through the array 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 ,已完成?

推荐答案

一种方法对信号异步函数完成使用的是完成处理。您已使用完毕处理程序火力地堡API中,有系统的框架大量的API,所以我不认为进一步解释。

One approach to signal completion of an asynchronous function is using a completion handler. You already used completion handlers in the Firebase API and there are many APIs in the system frameworks, so I don't explain that further.

由于这种方法,包住code到一个函数,比如 updateContacts 以完成处理程序。通常一个异步函数的返回计算的值或错误的。在某些情况下,它只是成功或失败 - 不返回值。在完成处理程序的特征码的前preSS这一点。你的函数 updateContacts 可能无法计算的价值,但它可能会失败或成功的反正。然后,您可以使用一个可选的错误:如果是,任务成功;否则,它包含发生的错误

Given this approach, wrap your code into a function, say updateContacts with a completion handler. Usually an asynchronous function returns the computed value or an error. In some cases, it just succeeds or fails - without returning a value. You express this in the signature of the completion handler. Your function updateContacts may not compute a value, but it may fail or succeed anyway. Then, you can use an optional error: if it is nil, the task succeeded, otherwise it contains the error that occurred.

当你的基本任务已经完成,与调用的结果完成处理。

When your underlying task has been completed, call the completion handler with the result.

注意:您的必须的保证,即完成处理会的最终名为

Note: You must ensure, that the completion handler will be eventually called!

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 当所有子任务已经完成 - 你可以利用调度组:

Now, when you have an array of asynchronous subtasks, that will be called in parallel and you want to signal completion of updateContacts when all subtasks have been completed - you can utilise dispatch groups:

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)
}

这篇关于确保异步操作已经完成了火力地堡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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