rxjs 的 of 运算符的问题

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

我有一个复杂的场景,我需要几个可观察的对象来获取一些数据。

我有一个类似以下的方法:

  private collectData(): Observable<any> {
    const defaultValues = {
      prop3: 'textsdfsdf',
      prop4: 122323,
    };
    let result: Observable<any>;
    if (this.withDialog) {
      result = this._dialog.open(MyDialogComponent).afterClosed();
    } else {
      result = of({});
    }

    return result.pipe(map((next) => ({ ...next, ...defaultValues })));
  }

此方法返回带有某种数据的可观察值。一些数据可以在对话框中输入。但输入数据是可选的,因此如果不需要,则只会将一些默认数据返回给下标。

此方法由不同的方法调用,例如添加更多数据或与后端通信,如下所示:

  private doSth(): Observable<any> {
    const sub = new Subject<any>();
    const data = this.collectData();

    data.subscribe((next) => {
      // Get some data from the backend or do some other stuff
      console.log(['Collected data', next]);
      const newData = {...next, anotherProp: true};
      sub.next(newData);
    });

    return sub.asObservable();
  }

此方法应该使用 Observable 返回数据和所有其他内容,并由第三种方法调用:

  public click() {
    this.doSth().subscribe((next) => {
      console.log(['Got some data', next]);
    });
  }

问题就在这里。只要我使用该对话框,一切都会正常。但是,当我不使用对话框时,因此不是

afterClosed()
可观察的,而是
of({})
可观察的,最后一个订阅永远不会获取数据。

您可以在这里找到完整的示例: https://stackblitz.com/edit/stackblitz-starters-qcayhz?file=src%2Fapp.component.ts

angular typescript rxjs observable subscription
1个回答
0
投票

无需通过从订阅处理程序发出值来链接可观察量,只需使用

pipe

如果您打算使用另一个可观察对象(例如http调用)来改变

doSth()
中的原始结果,那么您将使用
switchMap
而不是地图等。

  public click() {
    this.doSth().subscribe((next) => {
      console.log(`Got some data. With dialog? ${this.withDialog}`, next);
    });
  }

  private doSth(): Observable<any> {
    return this.collectData().pipe(
      map(next=>({ ...next, anotherProp: true }))
    )
  }

  private collectData(): Observable<any> {
    const defaultValues = {
      prop3: 'defaultProp3',
      prop4: 9999999999,
    };
    const  result= this.withDialog ? this._dialog.open(MyDialogComponent).afterClosed() : of({});
    return result.pipe(map((next) => ({  ...defaultValues,...next })));
  }

https://stackblitz.com/edit/stackblitz-starters-1vd2z5?file=src%2Fapp.component.ts

此外,您正在使用默认值覆盖实际数据,而您应该反过来做,因此应该是

 return result.pipe(map((next) => ({  ...defaultValues,...next })));

不是相反

示例输出:

Got some data. With dialog? true

{prop3: "defaultProp3", prop4: 9999999999, prop1: "text", prop2: 123, …}

Got some data. With dialog? false

{prop3: "defaultProp3", prop4: 9999999999, anotherProp: true}
© www.soinside.com 2019 - 2024. All rights reserved.