RXJS:返回外部可观察值的操纵值

问题描述 投票:2回答:3

我试图调用两个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功能?

angular typescript rxjs httpclient
3个回答
0
投票

你的例子很接近。

你想使用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仅适用于第一个发射值。


2
投票

您正在寻找的解决方案是这样的:

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作为第二个参数将让我们围绕这一点。


0
投票

使用mergeMap

return this.http.get(requestUrl)
            .mergeMap((response: User) => {
                const currentUser = response;
                currentUser.firstTimeLogin = this.isFirstTimeUser(response.id) === 'true' 
                return Observable.of(currentUser);
            })
© www.soinside.com 2019 - 2024. All rights reserved.