我试图了解RxJs中的Observables。我有一个页面,我需要显示特定网站的所有用户。 User和SiteUser实体位于不同的API端点中。我有以下端点
userService.getSiteUsers(siteId: string): Observable<SiteUser[]>;
其中
export class SiteUser {
site_id: string;
user_id: string;
}
和
userService.getUser(user_id: string): Observable<User>;
,其中
export class User {
id: string;
name: string;
email: string;
....
}
所以我必须做以下事情:
我可以很容易地做到这一点
let users: User[] = []; // this is bound in html view to a table
this.userService.getSiteUsers("my site id")
.subscribe((siteUsers) => {
for (let siteUser of siteUsers) {
this.userService.getUser(siteUser.user_id)
.subscribe((user) => {
users.push(user);
});
}
});
但这种方法感觉很脏或很麻烦。我确信有一种更清晰的Observable方法。我是Observables的新手,但据我所知,我应该可以做这样的事情(不是selectMany和mergeAll函数只是我的猜测,我尝试过它并没有用,我甚至找不到selectMany在rxjs库))
获取网站用户可观察数组 - &gt;对于可观察数组中的每个元素,创建用户可观察 - &gt;将它们全部合并到可观察的用户数组中 - &gt;订阅,所以像这样:
this.userService.getSiteUsers("my site id")
.selectMany((siteUser) => this.userService.getUser(user))
.mergeAll()
.subscribe((users) => {
this.users = users;
});
有人可以帮助,我无法让它工作
EDIT ------
也许是这样的
this.userService.getSiteUsers("my site id")
.switchMap(
(siteUsers) => {
let userQueries: Observable<User>[] = [];
for (let siteUser of siteUsers) {
userQueries.push(this.userService.getUser(siteUser.user_id));
}
return Observable.forkJoin(userQueries);
}
)
.subscribe((users) => {
this.users = users;
});
答案 0 :(得分:6)
如果一个http呼叫依赖于另一个http呼叫,您应该使用.flatMap()
/ .mergeMap()
运营商。
例如在你的情况下会有类似的事情,
this.userService.getSiteUsers("my site id")
.switchMap(
(siteUsers) => {
let userQueries: Observable<User>[] = [];
for (let siteUser of siteUsers) {
userQueries.push(this.userService.getUser(siteUser.user_id));
}
return Observable.forkJoin(userQueries);
}
)
.subscribe((users) => {
this.users = users;
});
答案 1 :(得分:1)
尝试这样的事情:
this.userService.getSiteUsers("my site id")
.flatMap((siteUsers) => {
// map every user into an array of observable requests
const usersObservables = siteUsers.map(siteUser => this.userService.getUser(siteUser.user_id)).map((res:Response) => res.json())
return Observable.forkJoin(...usersObservables)
}).subscribe(users => {
//you have all your users now;
console.log(users)
});
我们在这里使用spread运算符:
return Observable.forkJoin(...usersObservables)
所以我们将数组转换为参数,如下所示:
return Observable.forkJoin(observableUser1, observableUser2, observableUser...)