如何修改retry操作符实现每次重试使用不同上游参数,最多重试10次
问题核心原因
你现有代码的问题在于generateRandomName()会在构建Publisher链的时候就立刻执行,生成固定值传给checkIfNameIsAvailable,后续retry触发的重订阅不会重新执行这个生成随机名的逻辑,所以每次重试参数都相同。
最简解决方案:用
Deferred包装上游Publisher Deferred会在每次收到订阅请求时才执行闭包内的代码构建Publisher,刚好可以满足每次重试都重新生成随机参数的需求,修改后的代码如下:
Deferred { // 每次订阅/重试都会重新执行这个闭包,生成新的随机名 checkIfNameIsAvailable(generateRandomName()) } .retry(10) // 最多重试10次,每次都会触发Deferred重新构建上游 .sink( receiveCompletion: { completion in // 处理完成/失败逻辑 }, receiveValue: { value in // 处理成功逻辑 } ) .store(in: &cancellables)
进阶可控方案:自定义重试逻辑(可选)
如果你需要更精细的控制,比如只在特定错误类型下重试、或者添加重试间隔,可以用tryCatch配合计数器实现:
var retryCount = 0 let maxRetryTimes = 10 checkIfNameIsAvailable(generateRandomName()) .tryCatch { error -> AnyPublisher<YourOutputType, Error> in guard retryCount < maxRetryTimes else { throw error // 超过重试次数直接抛出错误 } retryCount += 1 // 可按需添加重试延迟:.delay(for: .seconds(1), scheduler: DispatchQueue.main) return checkIfNameIsAvailable(generateRandomName()) .eraseToAnyPublisher() } .sink( receiveCompletion: { completion in // 处理完成逻辑 }, receiveValue: { value in // 处理成功逻辑 } ) .store(in: &cancellables)
*注意替换代码中的YourOutputType为你的checkIfNameIsAvailable方法返回的Publisher的实际输出类型。
内容的提问来源于stack exchange,提问作者Artem Krachulov
相关产品推荐
相关产品推荐

