我是RxSwift的初学者,我正试着从一个简单的登录界面开始。所以我有2个文本字段和一个登录按钮,它绑定到PublishSubject
所以每次点击按钮,我都会发送网络请求来执行身份验证。
由于身份验证可能失败,我选择了Driver
,因此每次点击按钮都可以重播我的请求。
我有两个版本,我认为是相同的代码,但一个工作,一个不。 我试图了解幕后发生的事情。
这是第一个有效的版本(每次触摸按钮时请求):
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()
}
这是一个不起作用的(请求仅在第一次点击时触发):
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()
有关信息,这是我的属性声明:
let email = Variable("")
let password = Variable("")
let signInTaps = PublishSubject<Void>()
let signIn: Driver<Result<AuthenticateResponse, APIError>>
答案 0 :(得分:11)
让我们分解第一个发生的事情(因为它们大致相同):
handlers = [ (dict1, do_stuff_dict1), (dict2, do_stuff_dict2), (dict3, do_stuff_dict3) ]
for whichDict, whichFunc in handlers:
try:
val = whichDict[key]
except KeyError:
continue
else:
whichFunc()
break
else:
do_stuff_not_found()
// 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()
}
的最新信号和密码,并将它们组合成email
s的元组。String
的最新结果组合在一起。除了使用observable而不是驱动程序之外,第二个示例大致相同。检查credentials
并查看每次点击按钮时是否收到活动。可能是信号正在释放的某个地方,实际上两个版本之间的唯一区别是使用驱动程序和可观察数据。
还要记住,使用驱动程序只是一个可观察的语法糖。
signInTaps
与
相同let intDriver = sequenceOf(1, 2, 3, 4, 5, 6)
.asDriver(onErrorJustReturn: 1)
.map { $0 + 1 }
.filter { $0 < 5 }
因此,当您使用observables而不是驱动程序时,您将丢失let intObservable = sequenceOf(1, 2, 3, 4, 5, 6)
.observeOn(MainScheduler.sharedInstance)
.catchErrorJustReturn(1)
.map { $0 + 1 }
.filter { $0 < 5 }
.shareReplay(1)
和.observeOn
。对于驱动程序,您可能只是看到了重放和缓存的值。