订阅调用 2 次,如何在 RxSwift 中取消订阅 observable

Subscription call 2 times, how to unsubscribe observable in RxSwift

重置密码呼叫发生了 2 次,我该如何删除该块中的订阅。

        let digits = [firstDigit, secondDigit, thirdDigit, fourthDigit, fifthDigit, sixthDigit]
        let digitsValid = digits.map { [=10=]?.textField.rx.text.orEmpty.map({ [=10=].count == 1 }).share(replay: 1) }
        let allDigitsFilled = Observable.combineLatest(digitsValid.map{ [=10=] ?? BehaviorRelay(value: false).asObservable()}).share(replay: 1)
        allDigitsFilled.subscribe (onNext: { [weak self] (boolArray) in
            guard let self = self else { return }
            let isFilled = boolArray.allSatisfy({ [=10=] })
            if isFilled {
                self.viewModel.resetPassword()
            } 
        }).disposed(by: disposeBag)

每次任何文本字段更改其内容时,都会调用您的 onNext 块。你的第一个目标应该是让它只在你想重置密码时调用块。

所以首先,您要将 .allSatisfy 放在 Observable.filter 调用中,这样只有当所有六个文本字段都恰好包含 1 个字符时,才会调用您的 onNext 块。一旦你这样做了,那么你可以简单地使用 .take(1) 一旦发出下一个值就会完成订阅。

像这样应该可以做到,而且看起来更干净:

let digits = [firstDigit, secondDigit, thirdDigit, fourthDigit, fifthDigit, sixthDigit]
let texts = digits.compactMap { [=10=]?.textField.rx.text.orEmpty }
Observable.combineLatest(texts)
    .filter { [=10=].allSatisfy { [=10=].count == 1 } }
    .map { _ in }
    .take(1)
    .subscribe(onNext: { [viewModel] in
        viewModel?.resetPassword()
    })
    .disposed(by: disposeBag)