RxSwift - 误解了一些概念

Yam*_*man 18 ios swift rx-swift

我是RxSwift的初学者,我试着从一个简单的登录屏幕开始.所以我有2个文本字段和一个登录按钮,它绑定到一个PublishSubject所以每次点击按钮时,我都会发送网络请求来执行身份验证.

由于身份验证可能会失败,Driver因此我每次单击按钮都可以重播我的请求.

我有2个版本,我认为是相同的代码,但一个工作,一个不.我试图了解幕后发生的事情.

这是第一个有效的版本(每次触摸按钮时请求):

let credentials = Driver.combineLatest(email.asDriver(), password.asDriver()) { ($0, $1) }
self.signIn = signInTaps
    .asDriver(onErrorJustReturn: ())
    .withLatestFrom(credentials)
    .flatMapLatest { email, password in // returns Driver<Result<AuthenticateResponse, APIError>>
        return provider.request(.Authenticate(email: email, password: password))
            .filterSuccessfulStatusCodes()
            .mapObject(AuthenticateResponse)
            .map { element -> Result<AuthenticateResponse, APIError> in
                return .Success(element)
            }
            .asDriver { error in
                let e = APIError.fromError(error)
                return Driver<Result<AuthenticateResponse, APIError>>.just(.Failure(e))
            }
            .debug()
    }
Run Code Online (Sandbox Code Playgroud)

这是一个不起作用的(请求只在第一次点击时触发):

let credentials = Observable.combineLatest(email.asObservable(), password.asObservable()) { ($0, $1) }
self.signIn = signInTaps.asObservable()
    .withLatestFrom(c)
    .flatMapLatest { email, password in // returns Observable<AuthenticateResponse>
        return provider.request(.Authenticate(email: email, password: password))
            .filterSuccessfulStatusCodes()
            .mapObject(AuthenticateResponse)
    }
    .map { element -> Result<AuthenticateResponse, APIError> in // returns Observable<Result<AuthenticateResponse, APIError>>
        return .Success(element)
    }
    .asDriver { error in // returns Driver<Result<AuthenticateResponse, APIError>>
        let e = APIError.fromError(error)
        return Driver<Result<AuthenticateResponse, APIError>>.just(.Failure(e))
    }
    .debug()
Run Code Online (Sandbox Code Playgroud)

有关信息,这是我的属性声明:

let email = Variable("")
let password = Variable("")
let signInTaps = PublishSubject<Void>()    
let signIn: Driver<Result<AuthenticateResponse, APIError>>
Run Code Online (Sandbox Code Playgroud)

bar*_*dog 11

让我们分解第一个发生的事情(因为它们大致相同):

// 1.
let credentials = Driver.combineLatest(email.asDriver(), password.asDriver()) { ($0, $1) }
// 2.
self.signIn = signInTaps
    .asDriver(onErrorJustReturn: ())
    // 3.
    .withLatestFrom(credentials)
    // 4.
    .flatMapLatest { email, password in // returns Driver<Result<AuthenticateResponse, APIError>>
    return provider.request(.Authenticate(email: email, password: password))
        .filterSuccessfulStatusCodes()
        .mapObject(AuthenticateResponse)
        .map { element -> Result<AuthenticateResponse, APIError> in
            return .Success(element)
        }
        .asDriver { error in
            let e = APIError.fromError(error)
            return Driver<Result<AuthenticateResponse, APIError>>.just(.Failure(e))
        }
        .debug()
}
Run Code Online (Sandbox Code Playgroud)
  1. 你将最新的信号email和密码结合起来,并将它们组合成一个Strings 元组.
  2. 这是您的登录信号,是以下所有信号的合成.
  3. credentials只需按一下按钮,即可将最新结果组合在一起.
  4. 每次点击按钮或电子邮件/密码发出时,您将取消当前信号并创建一个新电话信号(使用Moya),成功状态代码过滤,映射对象以及处理成功和错误.

第二个例子大致相同,只是你使用的是observable而不是驱动程序.signInTaps每次点击按钮时,请检查并查看是否收到了活动.可能是信号正在解除分配的某个地方,实际上两个版本之间的唯一区别是使用驱动程序和可观察对象.

还要记住,使用驱动程序只是一个可观察的语法糖.

let intDriver = sequenceOf(1, 2, 3, 4, 5, 6)
.asDriver(onErrorJustReturn: 1)
.map { $0 + 1 }
.filter { $0 < 5 }
Run Code Online (Sandbox Code Playgroud)

是相同的

let intObservable = sequenceOf(1, 2, 3, 4, 5, 6)
.observeOn(MainScheduler.sharedInstance)
.catchErrorJustReturn(1)
.map { $0 + 1 }
.filter { $0 < 5 }
.shareReplay(1)
Run Code Online (Sandbox Code Playgroud)

因此,当你使用了可观察的驱动程序,你失去.observeOnshareReplay.对于驱动程序,您可能只是看到了重放和缓存的值.

  • 嘿伙计们,我建议,阅读这篇文章(http://davesexton.com/blog/post/Hot-and-Cold-Observables.aspx).更好地理解"冷"和"热"的含义 (2认同)