在同步调用中执行异步任务

时间:2016-09-03 15:23:01

标签: ios swift asynchronous closures

我想注册一个异步执行的用户。但是,调用函数的行为是同步的,因为程序只应在成功创建用户时继续。 目前的实施是:

class SignUp: NSObject {

    // ...

    func signUpUser() throws -> Bool {
        guard hasEmptyFields() else {
            throw CustomErrorCodes.EmptyField
        }

        guard isValidEmail() else {
            throw CustomErrorCodes.InvalidEmail
        }

        createUser( { (result) in
            guard result else {
                throw CustomErrorCodes.UserNameTaken
            }
            return true // Error: cannot throw....
        })
    }


    func createUser( succeeded: (result: Bool) -> () ) -> Void {
        let newUser = User()
        newUser.username = username!
        newUser.password = password!

        // User is created asynchronously
        createUserInBackground(newUser, onCompletion: {(succeed, error) -> Void in
            if (error != nil) {
                // Show error alert
            } else {
                succeeded(result: succeed)
            }
        })

    }

}

在ViewController中,注册按如下方式启动:

do {
    try signup.signUpUser()
} catch let error as CustomErrorCodes {
    // Process error
}

但是,这不起作用,因为createUser不是投掷功能。如何在成功创建新用户时确保signUpUser()仅返回true?

2 个答案:

答案 0 :(得分:1)

你说:

  

在ViewController中,注册按如下方式启动:

do {
    try signup.signUpUser()
} catch let error as CustomErrorCodes {
    // Process error
}

但不要。这不是异步的工作方式。整个想法是你不等待。如果你等待,它不是异步的。这意味着你要阻止,这就是你不能做的事情。

相反,请在异步过程结束时安排回调。当你听说事情成功与否时,那就是你。看看下载任务委托的结构:

https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSessionDownloadTask_class/

下载任务回调代理,让它知道我们是否成功完成。这是您希望与异步任务建立的关系。你想成为那个代表。

答案 1 :(得分:0)

你需要调整自己的想法。而不是尝试编写我们需要等待异步事件的同步方法,而是编写一个完成闭包的方法。该方法将立即返回,但是一旦异步过程完成,它就会调用完成闭包。当你调用这样一个方法时,你会在完成作业后调用的不完整闭包中传入代码。