RXJS:返回外部 observable 的操作值

     2023-03-31     141

关键词:

【中文标题】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。

angular之rxjs基础操作(代码片段)

一:处理异步(Observable)①,首先引入importObservablefrom‘rxjs‘;②,使用setTimeOut来模拟延迟,返回Observable对象句柄varstream:Observable<string>=newObservable(observer=>setTimeout(():void=>observer.next("okokok"); 查看详情

在 RxJS Observable 中“展平”数组的最佳方法

...述】:我的后端经常将数据作为一个RxJS5Observable中的数组返回(我使用的是Angular2)。我经常发现自己想使用RxJS操作符单独处理数组项,我使用以下代码(JSBin):constd 查看详情

RxJS 5,将 observable 转换为 BehaviorSubject(?)

】RxJS5,将observable转换为BehaviorSubject(?)【英文标题】:RxJS5,convertinganobservabletoaBehaviorSubject(?)【发布时间】:2018-02-2218:12:07【问题描述】:我有一个父observable,一旦它有一个订阅者,它将进行查找并发出一个值,然后完成。我想... 查看详情

使用 Rxjs 6 在 Angular 6 中返回一个空/空的 Observable

】使用Rxjs6在Angular6中返回一个空/空的Observable【英文标题】:Returnanull/emptyObservableinAngular6withRxjs6【发布时间】:2018-12-2806:36:51【问题描述】:我正在使用Rxjs6开发Angular6,而我有一个关于如果响应失败或有异常返回null/emptyObservabl... 查看详情

Rxjs Observable 数组在给定的开始和结束值之间进行选择

】RxjsObservable数组在给定的开始和结束值之间进行选择【英文标题】:RxjsObservablearrayselectbetweengivenstartandendvalues【发布时间】:2021-10-0207:46:28【问题描述】:我有一个Observable数组,如下所示:persons$:Observable<Person[]>=newObservabl... 查看详情

如何使用 catchError() 并且仍然返回带有 rxJs 6.0 的类型化 Observable?

】如何使用catchError()并且仍然返回带有rxJs6.0的类型化Observable?【英文标题】:HowdoIusecatchError()andstillreturnatypedObservablewithrxJs6.0?【发布时间】:2018-10-1902:08:58【问题描述】:cd所以我正在尝试将我的一些Angular5代码迁移到6,并且... 查看详情

Rxjs toPromise 行为不同于 observable

...问题描述】:我有一个简单的例子,其中两个方法创建并返回一个承诺。第二个方法buildRedCar()调用第一个方法buildCar(),修改promise返回的值,从自身返回另一个promise。代码然后调用buildRedCa 查看详情

RxJs 5 share() 操作符是如何工作的?

...的latestdocs。Jsbin为问题here.如果我用一系列0到2创建一个observable,每个值间隔一秒:varsource=Rx.Observable.i 查看详情

你如何使用 RxJS v5 返回 new Observable(function(observer) ...?

】你如何使用RxJSv5返回newObservable(function(observer)...?【英文标题】:HowdoyoureturnnewObservable(function(observer)...withRxJSv5?你如何使用RxJSv5返回newObservable(function(observer)...?【发布时间】:2016-03-0416:13:28【问题描述】:我正在尝试用Observab... 查看详情

rxjs:单播和多播

参考技术A单播的意思是,每个普通的Observables实例都只能被一个观察者订阅,当它被其他观察者订阅的时候会产生一个新的实例。也就是普通Observables被不同的观察者订阅的时候,会有多个实例,不管观察者是从何时开始订阅,... 查看详情

取消订阅 Rxjs finalize 操作符

...述】:问:我有一个问题。finalize操作符在源完成或完成Observable时被调用。这很清楚。但是我们如何预测它不会因为Sourceobservable的变化而再次发出值呢?或者finalize将在完成第一次发射后终止原始Observable。即不再 查看详情

如何为 Subject RxJS observable 分配初始值?

】如何为SubjectRxJSobservable分配初始值?【英文标题】:HowtoassignaninitialvaluetoSubjectRxJSobservable?【发布时间】:2017-08-2205:00:23【问题描述】:我正在开发一个Angular2应用程序,我需要更改列表中列的顺序,单击标题(作为数据表工作... 查看详情

RxJs。如果我有两个 observable,如何抛出错误并继续发出值?

】RxJs。如果我有两个observable,如何抛出错误并继续发出值?【英文标题】:RxJs.HowtothrowerrorandcontinueemitingvaluesifIhaveatwoobservable?【发布时间】:2021-12-2704:39:37【问题描述】:https://stackblitz.com/edit/rxjs-catcherror-withmapoperators-lwutxg?file=... 查看详情

Rxjs:扫描操作符

...的属性“getTime”,为什么会发生这种情况?/p>this.clock=Observable.merge(this.click$,Observable.interval(5000)).startWith(newDate()).ma 查看详情

你必须知道的6个rxjs的操作符(代码片段)

1.ConcatconstgetPostOne$=Rx.Observable.timer(3000).mapTo(id:1);constgetPostTwo$=Rx.Observable.timer(1000).mapTo(id:2);Rx.Observable.concat(getPostOne$,getPostTwo$).subscribe(res=>console.log(re 查看详情

在 React 中使用 RxJs 链接 Observable 的最佳方法

】在React中使用RxJs链接Observable的最佳方法【英文标题】:BestwaytochainObservablesusingRxJsinReact【发布时间】:2021-01-0111:25:58【问题描述】:在这种情况下,最好的办法是链接Observables并在所有订阅完成后调度SEARCH_QUERY_COMPLETE操作?我... 查看详情

rxjs中observable和subject的异同

参考技术A最近对RXJS中的Observable和Subject有了更多的了解,特在此记录。在pull系统中,消费者决定何时从数据生产者中接收数据,生产者本身不知道数据何时会被传递给消费者,调用函数就是一个典型的pull系统,函数本身不知道... 查看详情

RxJs:根据字段值更改创建可观察对象

...根据字段值更改创建可观察对象【英文标题】:RxJs:Createobservablefromfieldvaluechanging【发布时间】:2017-09-2210:36:11【问题描述】:我想创建一个Observable使用源变量:this.pending。我想创建一个Observable,它会在每次this.pending值更改时生... 查看详情