【发布时间】:2018-10-06 04:08:10
【问题描述】:
我有以下数据结构:
export class Repo {
id: number;
name: string;
contributors: Contributor[];
}
export class Contributor {
id: number;
login: string;
}
我正在使用Observable<Repo> 获取所有回购数据,但我想在外部Repo 被认为完全发出之前在内部调用另一个可观察的Observable<Contributor> 来填充所有贡献者。我不知道该怎么做。我有以下代码。
private repos: Repo[] = [];
getRepos(orgName: string): void {
const repoBuild: Repo[] = [];
this.githubService.getRepos(orgName).pipe(
// this here won't wait for all contributors to be resolved
map(repo => this.getRepoContributors(orgName, repo))
).subscribe(
repo => repoBuild.push(repo),
error => {
this.repos = [];
console.log(error);
},
() => this.repos = repoBuild
);
}
// fetches contributors data for the repo
private getRepoContributors(orgName: string, repo: Repo): Repo {
const contributors: Contributor[] = [];
repo.contributors = contributors;
this.githubService.getRepoContributors(orgName, repo.name)
.subscribe(
contributor => {
// add to the total collection of contributors for this repo
contributors.push(contributor);
},
error => console.log(error),
() => repo.contributors = contributors
);
return repo;
}
我承认我对Observable 的理解是有限的,我为此苦苦挣扎了好几个小时。我尝试在 StackOverflow 上找到适合我的东西,但我仍然找不到有效的解决方案。任何帮助将不胜感激!
(代码是用Angular 5编写的)
解决方案:
我使用了下面的@joh04667 建议并最终让它发挥作用。这是我的做法:
getRepos(orgName: string): void {
const repoBuild: Repo[] = [];
this.githubService.getRepos(orgName).pipe(
// mergeMap() replaces `repo` with the result of the observable from `getRepoContributors`
mergeMap(repo => this.getRepoContributors(orgName, repo))
).subscribe(
repo => repoBuild.push(repo),
error => {
this.repos = [];
console.log(error);
},
() => this.repos = repoBuild
);
}
// fetches contributors data for the repo
private getRepoContributors(orgName: string, repo: Repo): Observable<Repo> {
repo.contributors = []; // make sure each repo has an empty array of contributors
return this.githubService.getRepoContributors(orgName, repo.name).pipe(
// tap() allows us to peek on each contributor and add them to the array of contributors
tap(contributor => {
// add to the total collection of contributors for this repo
repo.contributors.push(contributor);
}),
// only picks the last contributor and replaces him/her with the repo
last(
() => false,
() => repo,
repo
)
);
}
在我使用last() 的最后一部分中,我基本上告诉Observable,即使它会处理所有值,我只会使用最后一个值。最后一个是Contributor 类型,但我将其替换为默认值(repo),它允许我将返回类型从Observable<Contributor> 更改为Observable<Repo>,这正是我需要的更高级别可观察。
【问题讨论】:
-
您是否尝试过使用 switchmap 或 flatmap 运算符
标签: angular typescript observable