gpt4 book ai didi

ios - rxSwift Observable 依赖

转载 作者:行者123 更新时间:2023-11-29 00:09:02 24 4
gpt4 key购买 nike

我是 rxSwift 的新手。我有 3 个可观察对象,checkAccount、fetchMails 和 fetchFolders。
fetchMails 和 fetchFolders 取决于 checkAccount 结果。如何使用 UIButton Tap 调用 fetchMails 和 fetchFolders 操作?如果 checkAccount 成功,我不会在每次 fetchMails 和 fetchFolders 时运行它。如果 checkAccount 失败,我想在 fetchMails 和 fetchFolders 时重试 checkAccount。我怎样才能达到这个目的?这是我的代码:

@IBOutlet weak var btn1: UIButton!
@IBOutlet weak var btn2: UIButton!
var checkAccountO: Observable<Bool>?
let bag = DisposeBag()

let fetchO: Observable<[String]> = Observable.create { observer in
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1000)) {
observer.onNext(["1","2"])
}
return Disposables.create()
}

let fetchFolderO: Observable<[String]> = Observable.create { observer in
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1000)) {
observer.onNext(["folder1","folder2"])
}
return Disposables.create()
}
override func viewDidLoad() {
super.viewDidLoad()

fetchFolders().subscribe { (evetn) in
print("folders \(evetn)")
}.addDisposableTo(bag)

fetchMails().subscribe { (evetn) in
print("mails \(evetn)")
}.addDisposableTo(bag)
}

func checkAccount() -> Observable<Bool> {
if let ob = checkAccountO {
return ob
}
checkAccountO = Observable.create { (observer) -> Disposable in
print("checking...")
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1000)) {
let i = arc4random() % 2
if i == 0 {
print("succ")
observer.onNext(true)
observer.onCompleted()
}else {
print("failed:\(i)")
let err = NSError.init(domain: "err", code: 1001, userInfo: nil)
observer.onError(err)
}
}
return Disposables.create()
}.retry(3).shareReplay(1)
return checkAccountO!
}

func fetchMails() -> Observable<[String]> {
return checkAccount().flatMap({ (_) -> Observable<[String]> in
return self.fetchO
})
}

func fetchFolders() -> Observable<[String]> {
return checkAccount().flatMap({ (_) -> Observable<[String]> in
return self.fetchFolderO
})
}

根据@Timofey Solonin的回答,我将可观察的fetchFoders和fetchMails从button.rx.tap更改为flatmap,如下所示,但仍然不知道如何使用retrywhen

    func fetchMails() -> Observable<[String]> {
let rxtap = btn1.rx.tap
return rxtap.flatMap { (_) -> Observable<[String]> in
return self.checkAccount().flatMap({ (_) -> Observable<[String]> in
return self.fetchO
})
}

}

func fetchFolders() -> Observable<[String]> {
let rxtap = btn2.rx.tap
return rxtap.flatMap { (_) -> Observable<[String]> in
return self.checkAccount().flatMap({ (_) -> Observable<[String]> in
return self.fetchFolderO
})
}
}

最佳答案

您可以使用 retryWhen 运算符。 flatMapretryWhencheckAccount 的错误流,如果 checkAccount 成功,您的操作将重试。

要从按钮启动流,您可以使用 button.rx.tapflatMap 它。

例如,如果您想从 button.rx.tapcheckAcount() 多次调用 fetchMail(),如果 fetchMail () 出错了可以使用:

btn1.rx.tap.flatMapLatest {
fetchMails().retryWhen{ errors in
errors.flatMapLatest{ _ in
checkAccount().retry() //or you can use retry(n) if you want to retry checkAccount limited amount of times.
//fetchMails() will repeat if checkAccount() will return anything. Just keep in mind that retryWhen block is not going to be called if checkAccount() was successful.
}
}
}

关于ios - rxSwift Observable 依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47131058/

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