Комбинировать: Издателю нравится Future, но с несколькими значениями

У меня есть сторонняя библиотека (Firestore), в которой есть этот метод

func listenToEvents(handler: ([Result], Error) -> Void)

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()
}

Итак, мой Publisher дает значение только один раз, потому что Future работает таким образом. Есть ли другой Publishers (или может быть другой подход) для этого?


person Paul T.    schedule 17.05.2020    source источник


Ответы (1)


Здесь возможен альтернативный подход. Нет необходимости в Defer, cause subject lives idle, and can send (pass-through) as many values aslibraryObject` будет жить.

Протестировано с 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()
}
person Asperi    schedule 17.05.2020