Во-первых, проблема заключалась в том, что функция оценивается и возвращается только издатель. Таким образом, проверка кэша выполняется каждый раз до того, как сетевой издатель будет подписан. Использование Deferred
- правильное решение для этого. Однако это все еще не решило проблему.
Вместо этого было решено сначала кэшировать общего издателя, пока сетевой запрос находится в состоянии ожидания, поэтому все запросы во время сетевого вызова будут использовать одного и того же издателя, а затем, когда он будет завершен. для кэширования Just
издателя для всех будущих вызовов:
public func getItem(_ id: String) -> AnyPublisher<Item?, Never> {
if let publisher = self.publisherCache[id] {
return publisher
}
let publisher = downloadItem(id)
.handleEvents(receiveOutput: {
// Re-cache a Just publisher once the network request finishes
self.publisherCache[id] = Just($0).eraseToAnyPublisher()
})
.share() // Ensure the same publisher is returned from the cache
.eraseToAnyPublisher()
// Cache the publisher to be used while downloading is in progress
self.publisherCache[id] = publisher
return publisher
}
Одно замечание: downloadItem(id)
является асин c и принимается на главном l oop. Когда я заменил downloadItem(id)
на Just(Item())
для тестирования, это не сработало, потому что вся цепочка издателя была оценена при создании. Используйте Just(Item()).recieve(on: Runloop.main)
, чтобы исправить это во время тестирования.