我刚开始学习合并,因此我不知道如何向API发出复杂的请求。
有必要创建一个应用程序,用户可以在其中的输入字段中输入公司的GitHub帐户的名称,并获得一个开放的仓库及其分支的列表。
有两种API方法:
- https://api.github.com/orgs/<ORG_NAME>/repos此方法按名称返回组织帐户存储库的列表。例如,您可以尝试请求Apple的存储库列表https://api.github.com/orgs/apple/repos
此方法的结构
struct Repository: Decodable {
let name: String
let language: String?
enum Seeds {
public static let empty = Repository(name: "", language: "")
}
}
- https://api.github.com/repos/<ORG_NAME>/<REPO_NAME>/branches此方法用于获取指定仓库中的分支名称。
此方法的结构
struct Branch: Decodable {
let name: String
}
因此,我需要得到一个这样的结构的数组。
struct BranchSectionModel {
var name: Repository
var branchs: [Branch]
}
为此我有两个职能:
func loadRepositorys(orgName: String) -> AnyPublisher<[Repository], Never> {
guard let url = URL(string: "https://api.github.com/orgs/\(orgName)/repos" ) else {
return Just([])
.eraseToAnyPublisher()
}
return URLSession.shared.dataTaskPublisher(for: url)
.map { $0.data }
.decode(type: [Repository].self, decoder: JSONDecoder())
.replaceError(with: [])
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
}
和
func loadBranchs(orgName: String, repoName: String) -> AnyPublisher<[Branch], Never> {
guard let url = URL(string: "https://api.github.com/repos/\(orgName)/\(repoName)/branches") else {
return Just([])
.eraseToAnyPublisher()
}
return URLSession.shared.dataTaskPublisher(for: url)
.map { $0.data }
.decode(type: [Branch].self, decoder: JSONDecoder())
.replaceError(with: [])
.receive(on: RunLoop.main)
.eraseToAnyPublisher()
}
这两个函数分别工作,但我不知道如何结束[BranchSectionModel]。我猜使用flatMap和sink,但不明白如何。
我不明白如何在一个线程中合并这两个请求。
1条答案
按热度按时间6ljaweal1#
当你想把一个发行商变成另一个发行商时,
.map
和.switchToLatest
。在这种情况下,因为你也想把一个发行商变成多个(然后再变成一个),MergeMany
也是一个有用的工具:虽然我是合并的忠实粉丝,但我不认为它特别适合这项任务,与async/await相比,async/await可能会更少一些混乱,看起来更干净。作为一个学习练习,这是一个很好的练习,但如果你要在真实的世界中解决这个问题,async/await可能会是我的首选。