簡體   English   中英

如何使用 RxSwift 在訂閱中執行訂閱?

[英]How to perform subscription within subscription using RxSwift?

目前我有以下工作代碼:

    mainView.saveButton.rx.tap.bind { [weak self] in
        if let self = self {
            // start indicator
            self.viewModel.save() // Completable
                .subscribe(onCompleted: { [weak self] in
                    // completed
                }, onError: { error in
                    // error
                })
                .disposed(by: self.disposeBag)
        }
    }.disposed(by: disposeBag)

但我知道這不是一個好方法(由於嵌套訂閱),所以我正在嘗試創建等效的工作(現在沒有成功):

    mainView.saveButton.rx.tap
        .do(onNext: { [weak self] in
            // start indicator
        })
        .flatMapFirst { _ in
            self.viewModel.save() // Completable
        }
        .subscribe(onError: { error in
            // error
        }, onCompleted: { [weak self] in
            // completed
        })
        .disposed(by: disposeBag)

訂閱關閉根本沒有調用。 為什么?

flatMap在其源(按鈕點擊)完成之前不會完成。 不能,因為如果用戶再次點擊按鈕,它必須准備好。

解決此問題的最常見方法是讓您的save() function 返回Single<Void>而不是Completable 如果您不想(或不能)這樣做,那么您可以使用andThen在完成時發送事件。

此外,您不希望出現錯誤來逃避 flatMap,因為這會破壞按鈕點擊。 這意味着您需要catch任何錯誤並將它們轉換為閉包中的下一個事件。 您可以使用materialize()catch並使用專用主題來做到這一點。 (例如,查看我的ErrorRouter 。)

像這樣的東西:

let errorRouter = ErrorRouter()
let saveSuccessful = mainView.saveButton.rx.tap
    .flatMap { [viewModel] in
        viewModel.save()
            .andThen(Observable.just(()))
            .rerouteError(errorRouter)
    }

Observable.merge(
    mainView.saveButton.rx.tap.map(to: true),
    saveSuccessful.map(to: false)
)
.bind(onNext: { isIndicatorVisible in
    // handle indicator
})
.disposed(by: disposeBag)

errorRouter.error
    .bind(onNext: { error in
        // handle error
    })
    .disposed(by: disposeBag)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM