好。我的Angular组件中有一些异步代码,运行正常。看起来像这样(简要):
export class SomeComponent {
user: User;
/* ... */
email: string;
/* ... */
private someMethod(): void {
/* some code here */
this.userService1.getUsers().subscribe(users => {
users.forEach(user => {
if (user.email && user.email === this.email) {
this.userService2.getUser(user.id).subscribe(foundUser => {
let someFields;
if (foundUser) {
someFields = (({ field1, field2 }) => ({ field1, field2 }))(foundUser);
}
this.user = {...user, ...someFields};
});
}
});
});
/*some code here */
}
}
我跳过一些类型和名称变量有点尴尬(但很简单)因为它不是重点。代码有效。但 我想封装用户构建的进程 (来自2个服务),因为我需要在不同的组件中使用它。我试过了,但是......
constructUser(email): Observable<IUser> {
let finalUser: IUser;
return this.userService1.getUsers().merge(users => {
return users.filter(user => {
if (user.email && user.email === email) {
return this.userService2.getUser(user.id).map(foundUser => {
let someFields;
if (foundUser) {
someFields = (({ field1, field2 }) => ({ field1, field2 }))(foundUser);
}
finalUser = {...user, ...someFields};
return Observable.of(finalUser);
});
}
});
});
}
我的WebStorm没有显示任何错误。但是在控制台中我得到了 this.userService1.getUsers(...)。merge不是一个函数。
我已尝试合并, concat , flatMap ,无论如何 - 但仍然没有成功。唯一的区别是我得到的错误。我对rxjs没有多少经验,所以我被卡住了。任何帮助或提示将不胜感激。
UPD。
解决了,但是7天(虽然赏金活跃),任何人仍然欢迎更简洁和功能性的解决方案:)
答案 0 :(得分:5)
我觉得这样的事情就是你想要的:
RxJs 5:
import 'switchMap' from 'rxjs/add/operator/switchMap';
import 'map' from 'rxjs/add/operator/map';
this.userService1.getUsers()
.map(users => users.find(userInList => userInList.email === "SomeEmail")) //Map the observable with users to a single user
.switchMap(user => this.userService2.getUser(user.id)) //Map the observable by an other observable
.subscribe(...doSomething with the result)
RxJs 6:
import {map, switchMap} from 'rxjs/operators';
this.userService1.getUsers().pipe(
map(users => users.find(userInList => userInList.email === "SomeEmail")), //Map the observable with users to a single user
switchMap(user => this.userService2.getUser(user.id)) //Map the observable by an other observable
).subscribe(...doSomething with the result)
答案 1 :(得分:0)
正确答案(跳过某些类型并更改变量的真实姓名):
非常感谢@Robin Dijkhof,他以正确的顺序给了我 rxjs运算符。
public constructUser(email: string): Observable<User> {
return this.userService1.getUsers().pipe(
map(users => users.find(userInList => userInList.email === email)),
switchMap(user => {
return this.userService2.getUser(user.id).map(foundUser => {
if (foundUser) {
return {...user, ...(({ field1, field2 }) => ({ field1, field2 }))(foundUser)};
} else {
return {...user};
}
});
})
);
}
现在,我可以轻松地使用该方法通过电子邮件抓取构建的用户(可能稍后我会用id替换电子邮件),例如:
this.myHelperService.constructUser(email).subscribe(user => {...});
我认为可以使解决方案更加实用和简洁(也许解决方案必须更加强大)... 所以!欢迎任何人,额外的50个奖励积分仍在这里7天=)
答案 2 :(得分:-2)
我认为你应该在做其他任何事情之前订阅
this.userService1.getUsers().subscribe(users => {...