RXJS:返回外部 observable 的操作值
Posted
技术标签:
【中文标题】RXJS:返回外部 observable 的操作值【英文标题】:RXJS: Return the manipulated value of outer observable 【发布时间】:2018-09-12 22:52:13 【问题描述】:我试图调用两个 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 函数?
【问题讨论】:
在你的例子中,你在哪里调用第二个 observable? isFirstTimeUser(response.id) 返回另一个 http Observable。 查看我的更新答案 你能更好地解释你想要做什么吗?我试图想出答案,但你的描述不清楚。 @codeepic 编辑有帮助吗? 【参考方案1】:您正在寻找的解决方案是这样的:
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
值 - 函数外部的变量(函数世界中的一个大禁忌)然后我们访问它再次在.map()
函数中。 concatMap
将投影函数作为第二个参数将帮助我们解决这个问题。
【讨论】:
【参考方案2】:你的例子很接近。
您想使用switchMap
,它取消订阅传入的可观察对象,并订阅下一个可观察对象。
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()
将应用于该函数返回的可观察对象。
之所以称为switchMap
,是因为this.http.get()
返回的可观察对象已取消订阅,并且使用了下一个可观察对象。这不会是this.http.get()
的问题,但请记住switchMap
仅适用于第一个 发出的值。
【讨论】:
这太美了!非常感谢!【参考方案3】:使用mergeMap
return this.http.get(requestUrl)
.mergeMap((response: User) =>
const currentUser = response;
currentUser.firstTimeLogin = this.isFirstTimeUser(response.id) === 'true'
return Observable.of(currentUser);
)
【讨论】:
你的例子我不清楚,所以我用了这个 这不是我的例子。这是我的问题。我正在为我的特定问题寻找解决方案,因为我不太精通 rxjs。你认为你可以编辑答案来解决我的问题吗? 在 rxjs 中你不应该修改除了可观察的发射之外的任何变量,在这里你改变 sessionManager,这在 RX 的上下文中是无效的 这是真的,如果你这样做sessionManager.currentUser = response
这是一个不好的做法。因为它是可观察流之外的副作用。
this.isFirstTimeUser(response.id) === 'true'
永远不会是真的。它返回一个可观察的。请参阅 OPs cmets。以上是关于RXJS:返回外部 observable 的操作值的主要内容,如果未能解决你的问题,请参考以下文章