簡體   English   中英

RxSwift正確地關閉處理預訂

[英]RxSwift properly dispose subscription in closure

我正在圍繞Firebase身份驗證功能編寫包裝器,以返回Observable並添加其他profileIncomplete狀態。 它基本上首先檢查用戶是否已登錄,如果已登錄,則檢查用戶的個人資料是否完整。 以下是我的代碼,我想知道是否可以在Observable.create訂閱一個observable,如果可以的話,在這種情況下如何正確處置該一次性對象? 在封閉內部創建一個DisposeBag

enum State {
    case loggedIn
    case profileIncomplete
    case notLoggedIn
}

func listenToAuthState() -> Observable<State> {
    return Observable.create { observable in
        let authStateHandle = Auth.auth().addStateDidChangeListener() { [weak self] (_, user) in
            guard let user = user else {
                observable.onNext(.notLoggedIn)
                return
            }
            let disposable = self?.listenToProfileCompleted(uid: user.uid).subscribe(onNext: { (completed) in
                if completed {
                    observable.onNext(.loggedIn)
                    observable.onCompleted()
                } else {
                    observable.onNext(.profileIncomplete)
                }
            })
            // How to dispose the disposable???
        }
        return Disposables.create { 
            Auth.auth().removeStateDidChangeListener(authStateHandle) }
        }
}

func listenToProfileCompleted(uid: String) -> Observable<Bool> { ... }

我認為在Observable.create內部(或在其他訂閱塊中)進行訂閱是一種代碼嗅覺。

看來您有兩個不同的問題。 stateChangedprofileCompleted

我將它們分為兩種不同的方法,讓listenToAuthState僅負責反映addStateDidChangeListener的結果,並為listenToProfileCompleted提供單獨的listenToProfileCompleted

這將使您有一個單獨的“就緒”(或者您想稱呼它),可以將兩者壓縮。 否則,如果在偵聽配置文件完成之前必須更改身份驗證狀態,請使用flatMap。

要處置資源,可以將其添加到DisposeBag。 像下面

func listenToAuthState() -> Observable<State> {
    return Observable.create { observable in
        var disposeBag:DisposeBag! = DisposeBag()
        let authStateHandle = Auth.auth().addStateDidChangeListener() { [weak self] (_, user) in
            guard let user = user else {
                observable.onNext(.notLoggedIn)
                return
            }
            let disposable = self?.listenToProfileCompleted(uid: user.uid).subscribe(onNext: { (completed) in
                if completed {
                    observable.onNext(.loggedIn)
                    observable.onCompleted()
                } else {
                    observable.onNext(.profileIncomplete)
                }
            }).disposed(by: disposeBag)
            // How to dispose the disposable???
        }
        return Disposables.create { 
            Auth.auth().removeStateDidChangeListener(authStateHandle)
            disposeBag = nil
        }
    }
}

暫無
暫無

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

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