Swift -排队组合请求



我正在处理一个组合请求,我想在某个事件后执行或排队执行。下面是场景-

  1. 新请求生成
  2. 检查应用程序是否有访问令牌
  3. 如果是,执行请求
  4. 如果没有,获取令牌,然后执行请求

下面是我的API,每个请求都将被触发-

public func fetchData<T: Codable>(to request: URLRequest) -> AnyPublisher<Result<T>, Error> {

if hasToken {
return self.urlSession.dataTaskPublisher(for: request)
.tryMap(self.parseJson)
.receive(on: RunLoop.main)
.subscribe(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
else {
// Store request somewhere
// Get token
// Execute stored request
}
}

如果有人能建议我如何处理代码中的else部分,我将非常感激。

如果快速连续发生多个请求,您开始使用的方法将不起作用。所有这些请求都将hasToken视为false,并且它们都将发起令牌请求。

你可以创建一个var tokenRequested: Bool属性并同步访问它。

我解决这个问题的方法——不确定这是否是最好的方法——是通过创建一个管道,所有请求都将通过该管道排队:

class Service {

private let requestToken = PassthroughSubject<Void, Error>()
private let tokenSubject = CurrentValueSubject<Token?, Error>(nil)
var c: Set<AnyCancellable> = []

init() {
requestToken.zip(tokenSubject)
.flatMap { (_, token) -> AnyPublisher<Token, Error> in
if let token = token {
return Just(token).setFailureType(to: Error.self)
.eraseToAnyPublisher()
} else {
return self.fetchToken()
.eraseToAnyPublisher()
}
}
.map { $0 as Token? }
.subscribe(tokenSubject)
.store(in: &c)
}

private func fetchToken() -> AnyPublisher<Token, Error> {
// async code to fetch the token
}
}

通过requestToken的任何请求都与tokenSubject的值同步,因此第一个请求与初始nil一起使用,但随后的请求等待直到发布下一个值,当前一个完成时发生。

然后,要发出请求,您将首先获得令牌getToken(),然后发出请求。

extension Service {
private func getToken() -> AnyPublisher<Token, Error> {
// request token, which starts queues it in the pipeline
requestToken.send(())
// wait until next token is available
return tokenSubject
.compactMap { $0 } // non-nil token
.first() // only one
.eraseToAnyPublisher()
}
func fetchData<T: Codable>(request: URLRequest) -> AnyPublisher<T, Error> {
getToken()
.flatMap { token in
// make request
}
.eraseToAnyPublisher()
}
}

相关内容

  • 没有找到相关文章

最新更新