【问题标题】:How to wrap an async function inside AnyPublisher?如何在 AnyPublisher 中包装异步函数?
【发布时间】:2020-09-02 08:02:39
【问题描述】:

假设我想创建一个异步函数,该函数调用一些随机 API 并返回一个随机 Int。我想用未来包装它

func createFuture() -> Future<Int, Never> {
  return Future { promise in
    promise(.success(Int.random(1...10))
  }
}

这每次都会返回相同的输出。相反,我想返回 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 ?

【问题讨论】:

    标签: ios swift combine


    【解决方案1】:

    Future 在初始化时缓存它的结果,这就是为什么你总是看到相同的结果。如果您希望每个订阅者收到不同的随机数,您可以改用Just

    func randomIntPublisher() -> AnyPublisher<Int, Never> {
        Just(Int.random(in: 1...10)).eraseToAnyPublisher()
    }
    

    如果你想在Publisher 中包装一个异步函数,你可以使用Future,只要确保每次在创建新订阅之前调用你的函数 - 这将确保你创建一个新的@987654326 @,因此结果不会被缓存并在不同订阅者之间共享。

    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 \($0)") }).store(in: &subscriptions)
    asyncRandomNumber().sink(receiveValue: { print("Second subscription received \($0)") }).store(in: &subscriptions)
    

    【讨论】:

    • 我知道,但是在 Combine 中没有像 Rx (Observable.create { ... } )?
    • @Godfather 不,Combine 中没有 Observable 这样的东西。 Publishers 有不同类型,它们是等价的。根据您的需要,Just 是最适合的 Publisher
    • 在“更好的例子”这个问题中查看我的编辑,你是如何让它发挥作用的?
    猜你喜欢
    • 1970-01-01
    • 2017-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-09
    • 2021-06-26
    • 1970-01-01
    相关资源
    最近更新 更多