我正在为HackerNews构建一个简单的iOS客户端。我正在使用their APIs,根据它,我将能够获得已排序的帖子ID(按new、Best和top排序)和将ID传递给请求的单个帖子项目。我面临的问题如下:一旦我获得了ID数组,我如何才能以有序的方式对每个帖子进行HTTP调用?以我目前的实现方式,我没有任何运气。例如,假设ID数组为[3001,3002,3003,3004]。我尝试调用该方法以在for循环中获取那些发布分派组和分派信号量的帖子,但我仍然将它们视为无序的,比如对项目3003的调用在3002之前完成,依此类推。
我使用的方法是:
@Published var posts: [Post] = []
func getPosts(feedType: FeedType){
posts = []
self.getFeedIDs(feedType: feedType).subscribe{ ids in
let firstFifteen = ids[0...15]
let dGroup = DispatchGroup()
let dQueue = DispatchQueue(label: "network-queue")
let dSemaphore = DispatchSemaphore(value: 0)
dQueue.async {
for id in firstFifteen{
dGroup.enter()
self.getPost(id: id).subscribe{ post in
self.posts.append(post)
dSemaphore.signal()
dGroup.leave()
}
dSemaphore.wait()
}
}
}
}
func getFeedIDs(feedType: FeedType) -> Observable<[Int]> {
return self.execute(url: URL(string: "https://hacker-news.firebaseio.com/v0/(feedType)stories.json")!)
}
func getPost(id: Int) -> Observable<Post>{
return self.execute(url: URL(string: "https://hacker-news.firebaseio.com/v0/item/(id).json")!)
}
func execute <T: Decodable>(url: URL) -> Observable<T> {
return Observable.create { observer -> Disposable in
let task = URLSession.shared.dataTask(with: url) { res, _, _ in
guard let data = res, let decoded = try? JSONDecoder().decode(T.self, from: data) else {
return
}
observer.onNext(decoded)
observer.onCompleted()
}
task.resume()
return Disposables.create {
task.cancel()
}
}
}
任何帮助都将不胜感激。
1条答案
按热度按时间ujv3wf0j1#
信号量没有任何意义,而且效率也很低。
使用Apple建议与TaskGroups结合使用的相同模式:收集词典中的数据,并在收到通知后按词典键对数据进行排序