我试图调用两个observable,第二个响应我操纵第一个然后返回一个新的observable。
return this.http.get(requestUrl)
.map((response: User) => {
sessionManager.currentUser = response;
return this.isFirstTimeUser(response.id);
})
.do((response: any) => {
console.log(response);
sessionManager.currentUser.firstTimeLogin = response === 'true';
return Observable.create(sessionManager.currentUser);
})
.toPromise();
isFirstTimeUser(response.id)是另一个返回observable的函数。
private isFirstTimeUser(userId: number): Observable<any> {
const requestUrl = 'someUrl';
return this.http.get(requestUrl, {responseType: 'text'});
}
我想做的就是从第一个http调用中获取用户对象,在第二个调用中使用用户的id
发出另一个请求,然后在我从第二个observable返回响应后,我更新第一个响应的属性并返回更新的第一个回复。我该如何实现这一目标?我应该关注什么rxjs功能?
你的例子很接近。
你想使用switchMap
取消订阅传入的observable,并订阅下一个observable。
return this.http.get(requestUrl)
.switchMap((response: User) => {
sessionManager.currentUser = response;
return this.isFirstTimeUser(response.id);
})
.map((response: any) => {
console.log(response);
sessionManager.currentUser.firstTimeLogin = response === 'true';
return sessionManager.currentUser;
})
.toPromise();
响应将传递给isFirstTimeuser()
,以下.map()
将应用于该函数返回的observabled。
它被称为switchMap
,因为this.http.get()
返回的可观测量是未订阅的,并且使用了下一个可观测量。这对this.http.get()
来说不是问题,但请记住,switchMap
仅适用于第一个发射值。
您正在寻找的解决方案是这样的:
getUser(): Observable<any>{
return this.http.get(reqUrl)
.do((res: User) => {
sessionManager.currentUser = res;
})
.switchMap((res: User) => {
return this.isFirstTimeUser(res.id);
})
.do((res: any) => {
console.log(response);
}
.map((res: any) => {
sessionManager.currentUser.firstTimeLogin = res === 'true';
return sessionManager.currentUser;
});
}
然后你只需要订阅getUser()
,你应该没事。根据纯函数的rxjs泛函范例,它仍然不是最好的代码。我想使用具有投影功能的concatMap
会让我们更接近理想,但它会起作用。
它不理想的原因是因为在第一个.do()
块中存在所需的副作用,我们更新sessionManager
值 - 函数外部的变量(函数世界中的一个大的no no)然后我们在.map()
函数中再次访问它。具有投影功能的concatMap
作为第二个参数将让我们围绕这一点。
使用mergeMap
return this.http.get(requestUrl)
.mergeMap((response: User) => {
const currentUser = response;
currentUser.firstTimeLogin = this.isFirstTimeUser(response.id) === 'true'
return Observable.of(currentUser);
})