组合:类似于 Future 的发布商,但具有多个值

Pau*_* T. 4 ios swift swiftui combine

我有 3d 方库 ( Firestore) 有这个方法

func listenToEvents(handler: ([Result], Error) -> Void)
Run Code Online (Sandbox Code Playgroud)

handler该方法被多次调用(在数据更新之后)。我想将其转换为Publisher

现在这是我的代码:

var resultsPublisher: AnyPublisher<[Result], Error> {
    Deferred { 
        Future { promise in
           libraryObject.listenToEvents { results, error in // called multiple times
              guard let results = results else {
                 promise(.failure(error))
                 return
              }

              // this can't be called several times,
              // because Future's promise is supposed to be called only once
              promise(.success(results))
           }
         }
    }
    .eraseToAnyPublisher()
}
Run Code Online (Sandbox Code Playgroud)

所以我的Publisher值只产生一次,因为Future这样工作。是否有任何其他Publishers(或可能是不同的方法)来实现这一目标?

Asp*_*eri 6

这是可能的替代方法。不需要Defer,因为主体处于闲置状态,并且可以发送(传递)尽可能多的值libraryObject

使用 Xcode 11.4 进行测试。

var resultsPublisher: AnyPublisher<[Result], Error> {
    let subject = PassthroughSubject<[Result], Error>()
    libraryObject.listenToEvents { results, error in // called multiple times
        guard let results = results else {
            subject.send(completion: .failure(error))
            return
        }

        subject.send(results)
    }
    return subject.eraseToAnyPublisher()
}
Run Code Online (Sandbox Code Playgroud)