我想查询不同的其他资源,并希望将结果合并到一个对象中。它是一个用户对象,每个用户都应该包含一个角色。我已经阅读过我可以使用flatMap来做到这一点,但我不能让它工作:
public getUsers(): Observable<User[]> {
var users: Observable<User[]> = this.someService.getUsers('[A_URL]') // returns Observable<User[]>
.flatMap(res=> {
// for every user call resource 'role' and add it to user object one by one ...
// return this.someService.getRoleByUser('[A_URL_WITH_USERID]')
}.map(res=>{
//add role to user object
// user.role = r;
});
);
return users;
}
我很抱歉伪代码,但我真的不懂语法。问题是,第二次资源调用需要第一次调用时每个用户的id。
答案 0 :(得分:2)
以下是您可以这样做的方法:
// This obs emits a SINGLE array of all users.
// Analog to what your `.getUsers()` method would return
const usersArray = Rx.Observable.of([
{ id: 1, name: 'user1' },
{ id: 2, name: 'user2' },
{ id: 3, name: 'user3' }
]);
// Obtain the role(s) for a given user.
const userRoles = function(userId) {
return Rx.Observable.of(`Role for user ${userId}`);
}
const obs = usersArray
// Flatten the array.
// Now each user is emitted as an individual value.
.mergeMap(val => val)
// Fetch user roles
.mergeMap(user => {
return userRoles(user.id).map(role => {
// Put together user + role
user.role = role;
// DO NOT FORGET to return below
return user;
});
})
// At this point, you have individual users with a `user.role` property
// being emitted in the stream.
// Unflatten the array if desired (to obtain a SINGLE array of ALL users)
.reduce((acc, curr) => acc.concat(curr), []);
// Final subscribe
obs.subscribe(val => console.log(val));
JS BIN演示此代码:http://jsbin.com/vucuga/4/edit?js,console
注意:
flatMap()
是mergeMap()
的别名。在RxJS 5(Angular使用的)中,我相信mergeMap()
是“官方”运营商。concatMap()
代替mergeMap()
。