如何在远程使用swift联合收割机之前正确地从缓存中提取
为了填充字段,我执行许多重复请求。我希望缓存结果并在下次使用缓存的值如何在远程使用swift联合收割机之前正确地从缓存中提取,swift,combine,Swift,Combine,为了填充字段,我执行许多重复请求。我希望缓存结果并在下次使用缓存的值 public func getItem(_ id: String) -> AnyPublisher<Item?, Never> { if let item = itemCache[id] { return Just(item).eraseToAnyPublisher() } return downloadItem(id: id) .map { item
public func getItem(_ id: String) -> AnyPublisher<Item?, Never> {
if let item = itemCache[id] {
return Just(item).eraseToAnyPublisher()
}
return downloadItem(id: id)
.map { item in
if let item = item {
itemCache[id] = item
}
return item
}
.eraseToAnyPublisher()
}
}
func downloadItem(_ id: String) -> AnyPublisher<Item?, Never> { ... }
但是,所有请求都在调用
downloadItem
downloadItem
在主队列中返回。我还尝试将整个getItem
函数包装到Deferred中,但结果相同。首先,问题是函数正在求值,只返回发布者。因此,在每次订阅网络发布服务器之前,都会对缓存检查进行评估。使用延迟
是正确的解决方法。然而,这仍然没有解决问题
相反,解决方案是在网络请求挂起时首先缓存共享发布服务器,这样网络调用期间的所有请求都将使用同一发布服务器,然后在完成后缓存发布服务器以供将来所有调用:
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
}
public func getItem(\uid:String)->AnyPublisher{
如果让publisher=self.publisherCache[id]{
返回发布者
}
让发布者=下载项(id)
.手柄通风口(接收输出:{
//网络请求完成后重新缓存Just publisher
self.publisherCache[id]=Just($0).eraseToAnyPublisher()
})
.share()//确保从缓存返回相同的发布服务器
.删除任何发布者()
//缓存下载过程中要使用的发布服务器
self.publisherCache[id]=发布者
返回发布者
}
需要注意的是,downloadItem(id)
是异步的,在主循环中接收。当我用Just(Item())
替换downloadItem(id)
进行测试时,这不起作用,因为整个发布链都是在创建时评估的。使用Just(Item()).recieve(on:Runloop.main)
在测试时修复该问题
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
}