如何在 AnyPublisher 中包装一个异步函数?
How to wrap an async function inside AnyPublisher?
假设我想创建一个调用一些随机 API 和 returns 随机 Int 的异步函数。我想用 future
包装它
func createFuture() -> Future<Int, Never> {
return Future { promise in
promise(.success(Int.random(1...10))
}
}
这将 return 我每次都得到相同的输出。相反,我想 return AnyPublisher.
func createAnyPublisher() -> AnyPublisher<Int, Never> { //This is invalid
return AnyPublisher<Int, Never> { seed in
seed.success(Int.random(in: 1...10))
}
}
一个更好的例子:
func guessNumber(num: Int) -> AnyPublisher<Bool, Never> {
asyncRandomNumber { winner in
if num == winner {
// return true
} else {
// return false
}
}
}
private func asyncRandomNumber(completion: (Int) -> Void) {
completion(Int.random(in: 1...10))
}
如何包装 asyncRandomNumber ?
Future
在初始化时缓存它的结果,这就是为什么你总是看到相同的结果。如果您希望每个订阅者收到不同的随机数,您可以使用 Just
。
func randomIntPublisher() -> AnyPublisher<Int, Never> {
Just(Int.random(in: 1...10)).eraseToAnyPublisher()
}
如果您想在 Publisher
中包装一个异步函数,您可以使用 Future
,只需确保每次在创建新订阅之前调用您的函数 - 这将确保您创建了一个新的 Future
,因此结果不会被缓存并在不同的订阅者之间共享。
func asyncRandomNumber(completion: @escaping (Int) -> Void) {
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
completion(Int.random(in: 1...100))
}
}
func asyncRandomNumber() -> AnyPublisher<Int, Never> {
Future { promise in
asyncRandomNumber(completion: { num in
promise(.success(num))
})
}.eraseToAnyPublisher()
}
asyncRandomNumber().sink(receiveValue: { print("First subscription received \([=11=])") }).store(in: &subscriptions)
asyncRandomNumber().sink(receiveValue: { print("Second subscription received \([=11=])") }).store(in: &subscriptions)
假设我想创建一个调用一些随机 API 和 returns 随机 Int 的异步函数。我想用 future
包装它func createFuture() -> Future<Int, Never> {
return Future { promise in
promise(.success(Int.random(1...10))
}
}
这将 return 我每次都得到相同的输出。相反,我想 return AnyPublisher.
func createAnyPublisher() -> AnyPublisher<Int, Never> { //This is invalid
return AnyPublisher<Int, Never> { seed in
seed.success(Int.random(in: 1...10))
}
}
一个更好的例子:
func guessNumber(num: Int) -> AnyPublisher<Bool, Never> {
asyncRandomNumber { winner in
if num == winner {
// return true
} else {
// return false
}
}
}
private func asyncRandomNumber(completion: (Int) -> Void) {
completion(Int.random(in: 1...10))
}
如何包装 asyncRandomNumber ?
Future
在初始化时缓存它的结果,这就是为什么你总是看到相同的结果。如果您希望每个订阅者收到不同的随机数,您可以使用 Just
。
func randomIntPublisher() -> AnyPublisher<Int, Never> {
Just(Int.random(in: 1...10)).eraseToAnyPublisher()
}
如果您想在 Publisher
中包装一个异步函数,您可以使用 Future
,只需确保每次在创建新订阅之前调用您的函数 - 这将确保您创建了一个新的 Future
,因此结果不会被缓存并在不同的订阅者之间共享。
func asyncRandomNumber(completion: @escaping (Int) -> Void) {
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
completion(Int.random(in: 1...100))
}
}
func asyncRandomNumber() -> AnyPublisher<Int, Never> {
Future { promise in
asyncRandomNumber(completion: { num in
promise(.success(num))
})
}.eraseToAnyPublisher()
}
asyncRandomNumber().sink(receiveValue: { print("First subscription received \([=11=])") }).store(in: &subscriptions)
asyncRandomNumber().sink(receiveValue: { print("Second subscription received \([=11=])") }).store(in: &subscriptions)