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

Rxjs combineLatest does returning the observable with in the suscribe

在我需要根据 userid 进行调用后,我正在尝试获取 Userid 和 serviceId,这里的 serviceId 问题是它没有将 observable 返回给 ts。

Service.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)));
      }
    })
}

Component.ts:

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

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

试试这个

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

您需要使用像 switchMap 这样的高阶映射运算符来从一个可观察对象映射到另一个。此外,subscribe() 函数只接受回调,return 只接受包含订阅的 Subscription 对象。

此外,如果 if 条件失败,您也不会 returning 任何东西。您可以 return 像 RxJS 常量 EMPTY 这样的可观察对象,如果条件失败,它会立即完成订阅。

此外

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

尝试以下方法

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

public getData(): Observable<any> {
  return forkJoin([
    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 EMPTY;
      }
    })
  );
}