ios - 方法在从 Combine Future Publisher 接收数据之前结束
问题描述
我有这样的代码:
import Cocoa
import Combine
func prepareURLRequest(for url: URL) -> URLRequest {
let request = URLRequest(url: url)
var token = "token"
print("start value: \(token)")
let subscription = Token()
subscription.getToken()
.sink(receiveCompletion: { _ in
print("subscription completed")
}, receiveValue: { value in
token = value
print("value received: \(token)")
})
print("new value: \(token)")
// attach received token to request
return request
}
class Token {
let token = PassthroughSubject<String,Never>()
func verify() -> Bool {
// TODO: Token verification logic
Bool.random()
}
func getToken() -> AnyPublisher<String,Never> {
return Future<String, Never> { promise in
if self.verify() {
let url = URLRequest(url: URL(string: "http://avatars.io/twitter/twostraws")!)
URLSession.shared.dataTask(with: url) { data, response, error in
print("Data Task started")
if let error = error {
print("error \(error)")
}
guard let data = data else {
preconditionFailure("data error")
}
guard let response = response as? HTTPURLResponse else {
preconditionFailure("response error")
}
print("data task received response with code: \(response.statusCode)")
promise(.success("\(response.statusCode)"))
}.resume()
} else {
print("keychain path")
sleep(2)
promise(.success("kwychain path success"))
}
}.eraseToAnyPublisher()
}
}
let url = URL(string: "http://avatars.io/twitter/twostraws")!
let request = prepareURLRequest(for: url)
代码应将下沉令牌附加到准备好的请求对象。现在唯一verify -> false path
按要求的顺序返回数据。当我尝试verify -> true
路径数据在 prepareURLRequest 结束后下沉时,它的生命。
如何解决此问题以使两个路径都以正确的顺序产生(并且在 prepareURLRequest 方法结束之前更新令牌?
解决方案
您遇到的问题是您没有用 Deferred 包装 Future。您编写的代码期望在请求请求之前不会进行 API 调用,但这并不是 Future 的工作方式。
一旦创建了 Future ,它就会调用它的底层异步 API 调用来呈现 - 并且您使用上面的 PassthroughSubject 意味着它已经完成了当您有订阅者请求数据时它的调用。解决这个问题的最好方法是封装Future
一个Deferred
发布者,它会等待创建它,直到订阅请求数据。
在Using Combine的 Future 参考页面中有一个用 Deferred 包装 Future 的示例 ,以及有关 Future 如何工作以及其他运算符如何使用它的更多信息。
推荐阅读
- php - 检查产品是否已存在于购物车中 - Cakephp 3
- session - 不显示刚刚登录的用户的用户名,但显示他们的个人资料图片
- azure-ad-b2c - Azure AD B2C Saml 身份验证
- python - python - 根据空白分割图像
- r - r 按 id 聚合或折叠特定列值
- powershell - 需要在与脚本不同的实例中运行 Powershell 命令
- java - 清除与 JPA / JPQL 的多对多关系
- python - 检测不可用的类型注释
- cron - 将 Crond“cronie”添加到 yocto build 时出错
- javascript - 滚动到另一个组件的特定标签