我在 a 上有以下擴展名,Publisher它允許我對 URL 請求進行分頁。我最初在一個特定用例中使用它,其中Output發布者的型別為CustomType。
extension Publisher where Output == CustomType,
Failure == Error {
func paginate(pageIdPublisher: CurrentValueSubject<String?, Never>) -> AnyPublisher<[User], Never> {
return self
.handleEvents(receiveOutput: { response in
if let maxId = response.pageId {
pageIdPublisher.send(maxId)
} else {
pageIdPublisher.send(completion: .finished)
}
})
.reduce([]) { allUsers, response in
return response.users allUsers
}
.catch { error in
Just([])
}
.eraseToAnyPublisher()
}
}
struct CustomType: Codable {
let users: [User]
let pageId: String?
}
這是這樣呼叫的:
func loadItem() async throws -> [String] {
let pageIdPublisher = CurrentValueSubject<String?, Never>(nil)
return try await pageIdPublisher
.flatMap { pageId in
urlSession
.publisher(
for: .item(pageId: pageId),
receiveOn: queue
)
}
.paginate(pageIdPublisher: pageIdPublisher) // <- This part
.singleOutput()
}
但是,我現在想讓它通用,以便它可以用于任何Output型別,只要它有 apageId和某種型別的陣列。
我嘗試使用這樣的協議Pageable:
protocol Pageable {
associatedtype T
var pageId: String? {get}
var items: [T] {get}
}
但是我不能將它與擴展一起使用,因為Output不能與包含associatedType.
這可能嗎?
uj5u.com熱心網友回復:
如果您將Output型別限制:為您的Pageable協議,并用于Output.T回傳的發布者的輸出型別,則該paginate方法應編譯:
extension Publisher where Output: Pageable,
Failure == Error {
func paginate(pageIdPublisher: CurrentValueSubject<String?, Never>) -> AnyPublisher<[Output.T], Never> {
return self
.handleEvents(receiveOutput: { response in
if let maxId = response.pageId {
pageIdPublisher.send(maxId)
} else {
pageIdPublisher.send(completion: .finished)
}
})
.reduce([]) { allItems, response in
return response.items allItems
}
.catch { error in
Just([])
}
.eraseToAnyPublisher()
}
}
使這個更通用的另一個想法是限制Output為一個Identifiable型別,其中ID是一個可選的,并提供一個額外的閉包引數來指定從Output到陣列的映射:
extension Publisher where Output: Identifiable,
Failure == Error {
func paginate<T, ID>(
pageIdPublisher: CurrentValueSubject<Output.ID?, Never>,
items: @escaping (Output) -> [T]
)
-> AnyPublisher<[T], Never>
where Self.Output.ID == ID?
{
...
}
}
您將在實作中使用response.id而不是response.pageId, 而items(response)不是response.items。例如,在呼叫站點,您將傳入\.users閉包引數。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/402331.html
標籤:
上一篇:處理bash腳本中的特殊字符
