Rxjs的combineLatest确实返回了订阅中的可观察值

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

在需要根据 userid 进行呼叫后,我尝试获取 Userid 和 serviceId,这里的 serviceId 问题是它没有将可观察值返回到 ts。

服务.ts

function getData():observable<any>{
   combineLatest([
      this.activeSellService.getActiveSellServiceId(),
      this.authService.getUserId(),
    ]).subscribe(([serviceId, userId]) => {
      if (serviceId&& userId) {
        const Url =
          'users/' +
          `${userId}` +
          '/services/' +
          `${serviceId}` +
          '?value=test
        return this.http.get<any>(this.endPoint.getUrl(encodeURI(Url)));
      }
    })
}

组件.ts:

 this.service.getData().subscribe(data=>{console.log(data));

甚至它不会在控制台中打印数据,因为服务没有返回可观察的。请帮我解决这个问题。否则我们可以在 rxjs 中采用不同的解决方案吗?

angular rxjs angular9 fork-join combinelatest
2个回答
2
投票

试试这个

function getData():observable<any>{
   return combineLatest(
      this.activeSellService.getActiveSellServiceId(),
      this.authService.getUserId(),
    ).pipe(mergeMap([serviceId, userId]) => {
      if (serviceId && userId) {
        const Url =
          'users/' +
          `${userId}` +
          '/services/' +
          `${serviceId}` +
          '?value=test
        return this.http.get<any>(this.endPoint.getUrl(encodeURI(Url)));
      }
    })
}

注意combinelatest的参数并且getData中没有订阅

例如在 stackblitz 中:

https://stackblitz.com/edit/angular-rxjs-combinelatest-hjyfa6?file=src/app/app.component.ts


2
投票

您需要使用高阶映射运算符(如

switchMap
)从一个可观察到的映射到另一个。此外,
subscribe()
函数仅接受回调并返回包含订阅的
Subscription
对象。

此外,如果

if
条件失败,您也不会返回任何内容。您可以返回像 RxJS 常量
NEVER
这样的可观察量以不发出任何内容,或返回
of(null)
以发出
null

此外

  1. observable<any>
    必须是
    Observable<any>
  2. 您还没有从函数中返回。
  3. Typescript 中不需要
    function
    关键字。相反,您可以提及范围标识符。
  4. 您将字符串连接与模板文字混合在一起。虽然它在语法上没有错误,但我认为最好坚持使用其中一个。
  5. 从函数的上下文猜测,我相信您希望发出一次请求并完成它。而不是
    combineLatest
    提供的数据流。在这种情况下,您可以使用
    forkJoin
    代替。但请注意,
    forkJoin
    仅在所有源完成时才会发出。

尝试以下方法

import { Observable, forkJoin, NEVER, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';

public getData(): Observable<any> {
  return combineLatest([
    this.activeSellService.getActiveSellServiceId(),
    this.authService.getUserId(),
  ]).pipe(
    switchMap(([serviceId, userId]) => {
      if (!!serviceId && !!userId) {
        const Url = `users/${userId}/services/${serviceId}?value=test`;
        return this.http.get<any>(this.endPoint.getUrl(encodeURI(Url)));
      } else {
        return NEVER; // <-- or `of(null)` to return `null` or whatever you wish to return
      }
    })
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.