我想分享一些关于RxSwift中内置机制的想法。我认为有一些方法可以实现所需的行为。
下面的代码只是一个理论,尚未经过测试。请不要 cmd+c cmd+v 这段代码。其目的是展示潜在解决方案的简化版本。
假设我们有:
var activityIndicator = ActivityIndicator()
var relayToken = BehaviorRelay<String?>(value: nil)
这个结构ActivityIndicator
在哪里有助于捕捉多个.Observables
理论上,请求方法看起来像这样:
func request<D, P, R>(data: D, parameters: @escaping (D, String) -> P, response: @escaping (P) -> Observable<R>) -> Observable<R> {
return Observable
.just(data)
.flatMap({ (data: D) -> Observable<R> in
return relayToken
.asObservable()
.filterNil()
.take(1)
.map({ parameters(data, $0) })
.flatMap({ (parameters: P) -> Observable<R> in
return activityIndicator.trackActivity(response(parameters))
})
})
}
在哪里:
data: D
- 初始请求参数
parameters: @escaping (D, String) -> P
- 将带有令牌的初始参数转换为完整请求参数的闭包。
response: @escaping (P) -> Observable<R>
- 将完整参数转换为正确请求的闭包Observable
。这是一个使用Moya或其他机制的地方。
该函数等待一个有效的令牌信号,当接收到一个正确的令牌时,它会将其转换为响应Observable
,该响应也由activityIndicator
. 此类跟踪需要知道所有“读取”调用何时完成。
结果 - 每个请求活动都会被跟踪,并且只有在收到有效令牌时才会启动任何请求。
第二个重要的事情 - 仅在没有活动请求时更改令牌:
func update(token: String?) {
_ = Observable
.just(token)
.flatMap({ (token: String?) -> Observable<String?> in
return activityIndicator
.asObservable()
.filter({ $0 == false })
.take(1)
.map({ _ in token })
})
.bind(to: relayToken)
}
因此,无论何时您决定更改令牌 - 您都可以通过此函数应用其更改。它观察所有请求的活动以及当它们都完成时 - 将应用更改。
希望对你有帮助,有需要可以提问。
编辑 1
“PATCH changePassword”可能不是正常请求之一,它的活动可能不会被跟踪activityIndicator
。
- 设置
relayToken = nil
何时需要更改密码(自此步骤以来,所有未来的正常请求都将等待正确的令牌)
- 等待已经开始的请求完成(
activityIndicator
将再次帮助)
- 发送“PATCH changePassword”请求更改密码/令牌
- 写入新令牌
relayToken = some
- 所有暂停的请求都将获得一个新的令牌并自动开始执行
- 需要时返回步骤 1
因此,只有在所有已经启动的请求都完成后,服务器才会使令牌失效。
我的解决方案阻止了所有新请求:
relayToken.asObservable().filterNil().take(1)
这意味着,虽然令牌是nil
- 等待。如果没有nil
- 只进行一次。