我有多种类型的搜索,所以一般的搜索方法有一个泛型类型T,多个简单的方法调用它根据需要指定类型。我想延迟搜索方法的启动(Combine 中的
debounce
)并且我想尽可能深地隐藏此代码。
我通常在我的项目中使用 async/await API,只有在必要时才使用合并。我没有找到使用 async/await 的内置解决方案,所以我将使用合并的
debounce
。 (请告诉我是否有更清洁的解决方案而不需要合并)
所以我必须从 async/await 到合并并返回。这需要使用
withCheckedContinuation
,它会丢失 T 并导致错误:
// simple generic specification using Event
func searchEvents(query: String) async -> [Event] {
await search(query: query)
}
// simple generic specification using Artist
func searchArtists(query: String) async -> [Artist] {
await search(query: query)
}
// debouncing layer between specifications and generic search
private func search<T>(query: String) async -> [T] where T: Codable, T: Identifiable {
await withCheckedContinuation { continuation in
Debouncer().debounce(query) { query in
Task {
// Generic parameter 'T' could not be inferred
let a = await self.performSearch(query: query) // <- error here
continuation.resume(returning: a)
}
}
}
}
// generic search function, details don't matter
private func performSearch<T>(query: String) async -> [T] where T: Codable, T: Identifiable {
...
}
// class performing simple debouncing
class Debouncer {
static var shared = Debouncer()
private var debounceSubscription: AnyCancellable?
func debounce(_ string: String, block: (String) -> ()) {
debounceSubscription?.cancel()
debounceSubscription = Just(string)
.debounce(for: .milliseconds(200), scheduler: DispatchQueue.global(qos: .background))
.sink { string in
block(string)
}
}
}
有没有一种优雅的方法可以让它自动理解类型而不将其作为参数传递(类型:T.Type,查询:String)?
告诉编译器
performSearch
将返回一个T数组
let a: [T] = await performSearch(query: query)