【问题标题】:How to return a function from inside a switch-case statement如何从 switch-case 语句中返回函数
【发布时间】:2021-09-06 04:46:19
【问题描述】:

在这种情况下如何中止或返回父函数:

enum MyError: String, Error {
case serverError = "This is a server error"
case condition1NotTrue = "Condition 1 is not true"
}

func myServerFunction(finishesSuccessful:Bool, completionHandler: @escaping (Result<Void, MyError>) -> Void) {
    if finishesSuccessful {
        completionHandler(.success(()))
    } else {
        completionHandler(.failure(.serverError))
    }
}

func myMainFunction(test1:Bool, uploadToServer:Bool, completionHandler: @escaping (Result<Void,MyError>) -> Void) {
    // check that condition test1 is true
    if !test1 {
        completionHandler(.failure(.condition1NotTrue))
        return // abort function to not execute the rest
    }
 
    if uploadToServer {
        myServerFunction(finishesSuccessful: false) { result in
            switch result {
            case .success():
                print("Successfully uploaded to server")
            case .failure(let error):
                print("Error uploading to server: \(error.rawValue)")
                completionHandler(.failure(error))
                return // <<<--- Here is my problem
            }
        }
    }

    // if !test1 && upload to server successful -> continue and update local data
    print("Local data will be updated now...")
}

myMainFunction(test1: true, uploadToServer: true) { result in
    switch result {
    case .success():
        print("myMainFunction succeeded")
    case .failure(let error):
        print("myMainFunction failed: \(error.rawValue)")
     }
}

基本上我想做的是检查一些数据,然后决定是否应该将其上传到服务器。如果不是,它将仅在本地使用,但如果需要上传,我必须确保成功。否则我不想更新我的本地数据。

这个输出

上传到服务器时出错:这是服务器错误 myMainFunction 失败:这是服务器错误 现在将更新本地数据...

return 如果 test1 不为真,则取消 myMainFunction 工作正常,并且不会更新本地数据。 return 以防 myServerFunction 失败,因为它只会停止 switch-case-statement。

有没有一种方便的方法可以直接从那里返回 myMainFunction?我能想到的唯一解决方法是在 switch 语句中设置一个 bool,然后在 switch 语句之后调用 return,但它看起来有点奇怪。

【问题讨论】:

  • 在调用服务器函数后,myMainFunction 中不应有任何代码。这看起来像是将许多功能/逻辑放入一个函数的情况,您在 myMainFunction 中有一个完成处理程序,因此使用它来评估结果并采取进一步的行动。
  • 它应该是 myMainFuncton 调用者的闭包主体,您应该在此处理您在获取成功或错误时的操作。
  • @JoakimDanielson myMainFunction 是我检查是否可以处理所有数据的地方。例如。名字没取,名字够长。并且 - 最后但同样重要的是 - 如果用户在线,则必须将其上传到服务器。这很重要——所以对我来说,在本地创建数据是一个通常的条件。然后我想再次从我的应用程序中的几个不同位置调用它 - 并且总是需要在其完成处理程序中具有相同的操作。这就是为什么我认为有一个 mainFunction 可以调用并且只处理用户警报是可行的方法,包括处理本地数据
  • 但是您肯定可以将其拆分为不同的较小功能吗?无论如何,要点是 myMainFunction 有一个完成处理程序,您应该在其中处理对服务器的调用的结果(和状态逻辑),而不是在 myMainFunction
  • myMainFunction 应该是从 UI 调用的那个。我认为主要问题是我想结合两个完成处理程序。 myMainFunction 之一和 myServerFunction 之一(顺便说一句,这是拆分的较小函数)。也许我宁愿将 myServerFunction 更改为 throw - 如果它 throws not complete myMainFunction

标签: swift function return switch-statement completionhandler


【解决方案1】:

按照@JoakimDanielson 的建议,我将 myServerFunction 更改为 throw 而不是使完成处理程序失败:

func myServerFunction(finishesSuccessful:Bool) throws {
    if finishesSuccessful {
        print("Upload to Server successful")
    } else {
        throw MyError.serverError
    }
}

现在我可以在 myMainFunction 中捕获错误

if uploadToServer {
    do {
        try myServerFunction(finishesSuccessful: false)
    } catch {
        completionHandler(.failure(.serverError))
        return
    }
}

【讨论】:

    猜你喜欢
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多