这是我目前正在使用的代码:
typealias ResponseHandler = (SomeResponse?, Error?) -> Void
class LoginService {
private var authorizeTokenCompletions = [ResponseHandler]()
func authorizeToken(withRefreshToken refreshToken: String, completion: @escaping ResponseHandler) {
if authorizeTokenCompletions.isEmpty {
authorizeTokenCompletions.append(completion)
post { [weak self] response, error in
self?.authorizeTokenCompletions.forEach { $0(response, error) }
self?.authorizeTokenCompletions.removeAll()
}
} else {
authorizeTokenCompletions.append(completion)
}
}
private func post(completion: @escaping ResponseHandler) {
// async
completion(nil, nil)
}
}
以上代码的思想是什么?
- authorizeToken函数可以根据需要调用多次(例如20次)
1.一次只能推送一个异步请求(post)。
1.调用authorizeToken函数的所有完成都应该使用与第一个完成的函数相同的参数。
用法:
let service = LoginService()
service.authorizeToken(withRefreshToken: "") { a, b in print(a)}
service.authorizeToken(withRefreshToken: "") { a, b in print(a)}
service.authorizeToken(withRefreshToken: "") { a, b in print(a)}
service.authorizeToken(withRefreshToken: "") { a, b in print(a)}
service.authorizeToken(withRefreshToken: "") { a, b in print(a)}
以上所有完成的结果都应与调用的第一个结果一起打印。
RxSwift可以做到这一点吗?
2条答案
按热度按时间vptzau2j1#
RxSwift可以做到这一点吗?
是的,这是可能的。RxSwift and Handling Invalid Tokens.
最简单的解决方案:
以上方法只有在所有请求(
subscribe
s)都在第一个请求完成之前发出的情况下才有效,就像你的代码一样。如果您希望存储响应以便在完成后使用,那么可以使用
replay
而不是share
。svgewumm2#
应答
是否可以使用RxSwift实现这一点
这是不可能的,因为每次我们触发函数时,它都会被调度,并且我们无法访问来自其他线程的回调。
您正在创建一个争用条件,一种解决方法是在一个单例中填充一次数据,而不是使用该单例多次调用函数。
一些其他方法也可以工作,单例只是一个示例。
竞态条件:争用条件是当操作序列的预期完成顺序变得不可预测时发生的情况,导致程序逻辑以未定义的状态结束