我想查询不同的休息资源,并希望将结果合并到一个对象中。它是一个用户对象,每个用户都应该包含一个角色。我已经阅读了我可以使用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。
这是
你可以做到的:
// 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()
。