-6ren">
gpt4 book ai didi

根据要求提供 Swift "retry"逻辑

转载 作者:IT王子 更新时间:2023-10-29 05:29:14 26 4
gpt4 key购买 nike

所以当我的上传请求失败时,我对如何实现重试逻辑有点迷茫。

这是我的代码,我想得到一些关于如何做的指导

func startUploading(failure failure: (NSError) -> Void, success: () -> Void, progress: (Double) -> Void) {
DDLogDebug("JogUploader: Creating jog: \(self.jog)")

API.sharedInstance.createJog(self.jog,
failure: { error in
failure(error)
}, success: {_ in
success()
})
}

最佳答案

这是一个通用的解决方案,可以应用于任何没有参数的异步函数,回调函数除外。我通过只有 successfailure 回调简化了逻辑,progress 应该不难添加。

所以,假设你的函数是这样的:

func startUploading(success: @escaping () -> Void, failure: @escaping (Error) -> Void) {
DDLogDebug("JogUploader: Creating jog: \(self.jog)")

API.sharedInstance.createJog(self.jog,
failure: { error in
failure(error)
}, success: {_ in
success()
})
}

匹配的 retry 函数可能如下所示:

func retry(times: Int, task: @escaping(@escaping () -> Void, @escaping (Error) -> Void) -> Void, success: @escaping () -> Void, failure: @escaping (Error) -> Void) {
task(success,
{ error in
// do we have retries left? if yes, call retry again
// if not, report error
if times > 0 {
retry(times - 1, task: task, success: success, failure: failure)
} else {
failure(error)
}
})
}

可以这样调用:

retry(times: 3, task: startUploading,
success: {
print("Succeeded")
},
failure: { err in
print("Failed: \(err)")
})

如果一直失败,上面将重试 3 次 startUploading 调用,否则将在第一次成功时停止。

编辑。具有其他参数的函数可以简单地嵌入到闭包中:

func updateUsername(username: String, success: @escaping () -> Void, failure: @escaping (Error) -> Void) {
...
}

retry(times: 3, { success, failure in updateUsername(newUsername, success, failure) },
success: {
print("Updated username")
},
failure: {
print("Failed with error: \($0)")
}
)

更新 retry 函数声明中的这么多@escaping 子句可能会降低其可读性,并增加消费时的认知负担功能。为了改进这一点,我们可以编写一个具有相同功能的简单通用结构:

struct Retrier<T> {
let times: UInt
let task: (@escaping (T) -> Void, @escaping (Error) -> Void) -> Void

func callAsFunction(success: @escaping (T) -> Void, failure: @escaping (Error) -> Void) {
let failureWrapper: (Error) -> Void = { error in
// do we have retries left? if yes, call retry again
// if not, report error
if times > 0 {
Retrier(times: times - 1, task: task)(success: success, failure: failure)
} else {
failure(error)
}
}
task(success, failureWrapper)
}

func callAsFunction(success: @escaping () -> Void, failure: @escaping (Error) -> Void) where T == Void {
callAsFunction(success: { _ in }, failure: failure)
}
}

可调用结构可以像普通函数一样被调用:

Retrier(times: 3, task: startUploading)(success: { print("success: \($0)") },
failure: { print("failure: \($0)") })

,或者可以通过app传播:

let retrier = Retrier(times: 3, task: startUploading)
// ...
// sometime later
retrier(success: { print("success: \($0)") },
failure: { print("failure: \($0)") })

关于根据要求提供 Swift "retry"逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34905900/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com