繁体   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