【问题标题】:Dont return value with observable, from the service layer to the component不要从服务层到组件返回可观察的值
【发布时间】:2021-12-18 22:00:04
【问题描述】:

我正在尝试将服务层的返回传递给组件。

我的服务与 api 连接:

 public getPerfilNew$(): Observable<PerfilInvestidor> {
            return this.http.get<PerfilInvestidor>(`${environment.api.basePosicaoConsolidada}/consolidado`)
              .pipe(
                map(res => res),
                shareReplay(1),
                catchError(err => {
                    console.log('Error in perfil', err);
                    return throwError(err);
                })
            )
        }

public getPositionConsolidated(): Observable<PosicaoConsolidada> {
    return this.http.get<PosicaoConsolidada>(`${environment.api.basePosicaoConsolidada}/consolidado`)
      .pipe(
        map(res => res),
        shareReplay(1),
        catchError(err => {
            console.log('Error investiments', err);
            return throwError(err);
        })
    )
}

在我的组件中:我试过了

public loadData() {
        //find out if the profile failed or no
        this.homeGuardService.getPerfilNew$.pipe(
            takeUntil(this.unsubscribe) 
        ).subscribe(res => {
            this.perfilInvestidor = res;
            this.perfilFailed = this.perfilInvestidor.status ? true : false;
            console.log('perfil is failed --->', this.perfilFailed)
        })

        //checking for investments
        this.homeGuardService.getPositionConsolidated().subscribe(res => {
            this.positionConsolidated = res
            if (this.positionConsolidated) {
                this.investments = true
            }
        });


        this.isEverthingFailed = !this.investments && this.perfilFailed
}

我需要外部订阅值来匹配我的变量 isEverthingFailed teria que utilizar 主题?行为主体?因为这样变量 investmentsperfilFailed 是未定义的

有了这么多的 observables 我会影响内存?我愿意接受建议

【问题讨论】:

    标签: javascript angular typescript rxjs


    【解决方案1】:

    您可以使用 forkJoin 或 combineLatest 获取两个流并订阅它们:

    public loadData() {
      forkJoin([this.homeGuardService.getPerfilNew$(), this.homeGuardService.getPositionConsolidated()])
        .subscribe(([perfile, position]) => {
            this.perfilInvestidor = perfile;
            this.perfilFailed = this.perfilInvestidor.status ? true : false;
            console.log('perfil is failed --->', this.perfilFailed)
            this.positionConsolidated = position
            if (this.positionConsolidated) {
                this.investments = true
            }
            this.isEverthingFailed = !this.investments && this.perfilFailed
        })
      )
    }
    

    【讨论】:

    • 我正在编辑问题,我有新问题。
    • 您目前没有返回任何东西。我更新了我的答案。显然你想要 perfil.status,所以只需返回它。
    • 我需要从其他订阅中获取数据并将它们组合成一个 if,但是当我尝试使逻辑脱离订阅时,变量是未定义的
    • 是的,这是异步的。你只需要在订阅中做任何你需要的事情。对于您还想做什么,确实没有足够的信息。有很多 rxjs 运算符可以帮助您,但我们不知道您的最终结果应该是什么。
    • 但是我怎样才能将数据留在订阅中?我需要从订阅内部发出值以在另一种方法中使用它
    【解决方案2】:

    1.问题

    这里没有足够的代码来查看到底发生了什么。但乍一看,从我的角度来看,它看起来像是一种竞争条件:

    您必须了解主题的工作原理。

    const sub = new Subject();
    sub.next(1);
    
    // If you subscribe here like:
       sub.subscribe(a => console.log(a))
    // Nothing will happen because Subject does not preserve the old values
    

    但如果你这样做:

    const sub = new Subject();
    
    // If you subscribe here like:
    sub.subscribe(a => console.log(a))
    
    sub.next(1);
    
    // You will get a print in a console since you emitted the value after you subscribed on the stream.
    

    在您的情况下,您似乎是在主题已经发出值之后订阅主题。

    还有:

     this.perfilClient$.subscribe(res => {
    

    您正在订阅 this.perfilClient$,但我没有看到您在该流上的哪个位置发出值?

    因此,如果您无法在 Subject 发出值之前同步您订阅的内容,您可以使用 ReplaySubject 或 BehaviourSubject

    2。问题 你只有几个可观察的,它并不多。但也有一些反模式,例如:

    1. 嵌套订阅
    2. 订阅回调函数为空 等等。

    RXJs主要是尽量避免副作用。

    【讨论】:

    • 几个组件需要知道 this.perfileFailed 是 false 还是 true,所以我不想在组件中执行此操作,但在核心状态服务中,我编辑问题,但我有新问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 2018-07-13
    • 2018-12-16
    • 1970-01-01
    相关资源
    最近更新 更多