Ios Combine CombineTest未等待上一个操作触发
如果在Playgroud中尝试此代码:Ios Combine CombineTest未等待上一个操作触发,ios,swift,combine,combinelatest,Ios,Swift,Combine,Combinelatest,如果在Playgroud中尝试此代码: import Combine import Foundation struct User { let name: String } private var subscriptions = Set<AnyCancellable>() var didAlreadyImportUsers = false var users = [User]() func importUsers() -> Future<Bool, Never
import Combine
import Foundation
struct User {
let name: String
}
private var subscriptions = Set<AnyCancellable>()
var didAlreadyImportUsers = false
var users = [User]()
func importUsers() -> Future<Bool, Never> {
Future { promise in
DispatchQueue.global(qos: .userInitiated).async {
sleep(5)
users = [User(name: "John"), User(name: "Jack")]
promise(.success(true))
}
}
}
func getUsers(age: Int? = nil) ->Future<[User], Error> {
Future { promise in
promise(.success(users))
}
}
var usersPublisher: AnyPublisher<[User], Error> {
if didAlreadyImportUsers {
return getUsers().eraseToAnyPublisher()
} else {
return importUsers()
.setFailureType(to: Error.self)
.combineLatest(getUsers())
.map { $0.1 }
.eraseToAnyPublisher()
}
}
usersPublisher
.sink(receiveCompletion: { completion in
print(completion)
}, receiveValue: { value in
print(value)
}).store(in: &subscriptions)
但我希望:
[User(name: "John"), User(name: "Jack")]
finished
如果使用sleep(5)
删除该行,则它会正确打印结果。这似乎是一个异步性问题。好像是.combinelateest(getUsers())
没有在等待导入器()
我以为combinelateest
正在处理这个问题?我错过了什么
(在我的真实代码中,有一个长时间运行的核心数据操作,而不是
sleep
)CombineTest
会等待,正如您正确预期的那样,但在您的情况下getUsers
已经准备好了一个值,即[]
;i、 e运行getUsers
时,users
是什么
实际上,您不需要使用combinelatetest
来“等待”某个异步操作发生。您可以直接链接发布者:
return importUsers()
.setFailureType(to: Error.self)
.flatMap { _ in
getUsers()
}
.eraseToAnyPublisher()
事实上,getUsers
甚至不需要,如果您可以假设users
是在importUsers
之后填充的:
return importUsers()
.map { _ in
self.users
}
.eraseToAnyPublisher()
你是对的。有趣的是,若我创建了一个变量
让users=getUsers()
,并在函数的两个分支中使用它,若这不起作用。我想这是因为当我创建let users=getUsers()
时,它的值将是[]
alreadyYes。我认为你对这个问题和之前的问题的困惑源于未来这个词——它实际上不会发生在“异步”的未来——它可能发生,但完全取决于承诺何时设定。否则,它只在运行时复制值。因此,您的getUsers
也可能是func getUsers(){Just(users)}
(加上故障类型设置)
return importUsers()
.map { _ in
self.users
}
.eraseToAnyPublisher()