gpt4 book ai didi

swift - RxSwift,分享+重试机制

转载 作者:行者123 更新时间:2023-11-28 09:50:51 25 4
gpt4 key购买 nike

我有一个可以成功或失败的网络请求

我已经将它封装在一个可观察对象中。我有 2 个请求规则

1) There can never be more then 1 request at the same time

-> there is a share operator i can use for this

2) When the request was Succeeded i don't want to repeat the same request again and just return the latest value

-> I can use shareReplay(1) operator for this

问题出现在请求失败时,shareReplay(1) 只会重放最新的错误,不会重新启动请求。

请求应在下一次订阅时重新开始。

有谁知道如何将它变成 Observable 链?

// scenario 1
let obs: Observable<Int> = request().shareReplay(1)
// outputs a value
obs.subscribe()
// does not start a new request but outputs the same value as before
obs.subscribe()

// scenario 2 - in case of an error
let obs: Observable<Int> = request().shareReplay(1)
// outputs a error
obs.subscribe()
// does not start a new request but outputs the same value as before, but in this case i want it to start a new request
obs.subscribe()

这似乎正是我想要的,但它包括将状态保持在可观察范围之外,有人知道我如何以更 Rx 的方式实现这一点吗?

enum Err: Swift.Error {
case x
}

enum Result<T> {
case value(val: T)
case error(err: Swift.Error)
}

func sample() {

var result: Result<Int>? = nil
var i = 0

let intSequence: Observable<Result<Int>> = Observable<Int>.create { observer in

if let result = result {
if case .value(let val) = result {
return Observable<Int>.just(val).subscribe(observer)
}
}
print("do work")
delay(1) {
if i == 0 {
observer.onError(Err.x)
} else {
observer.onNext(1)
observer.onCompleted()
}
i += 1
}
return Disposables.create {}
}
.map { value -> Result<Int> in Result.value(val: value) }
.catchError { error -> Observable<Result<Int>> in
return .just(.error(err: error))
}
.do(onNext: { result = $0 })
.share()

_ = intSequence
.debug()
.subscribe()

delay(2) {
_ = intSequence
.debug()
.subscribe()

_ = intSequence
.debug()
.subscribe()
}

delay(4) {
_ = intSequence
.debug()
.subscribe()
}
}


sample()

它只会在我们没有缓存任何东西时生成工作,但同样我们需要使用副作用来实现所需的输出

最佳答案

如前所述,RxSwift错误需要被视为 fatal error 。它们是您的流通常无法从中恢复的错误,而且通常是用户不会遇到的错误。

因此 - 发出 .error 的流或 .completed事件,将立即处理,你不会在那里收到任何更多事件。

有两种方法可以解决这个问题:

  1. 像刚才一样使用结果类型
  2. 使用 .materialize() (和 .dematerialize() 如果需要的话)。这些第一位运营商将把你的 Observable<Element>进入Observable<Event<Element>> ,这意味着您将得到一个元素,告诉您这是一个错误事件,但没有任何终止,而不是发出错误并终止序列。

您可以在 Adam Borek 关于此的精彩博客文章中阅读更多关于 RxSwift 中错误处理的信息:http://adamborek.com/how-to-handle-errors-in-rxswift/

关于swift - RxSwift,分享+重试机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48306567/

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