【问题标题】:Calling nested subscribe sequentially顺序调用嵌套订阅
【发布时间】:2019-08-05 15:08:45
【问题描述】:

调用一个依赖于另一个订阅方法的订阅

结构:

    this.example1().subscribe(res => {
      this.response = res;
    })


  example1(): Observable<any> | any {
    this.example2().pipe(
      catchError(err => {
        return throwError(err);
      })
    ).subscribe(res => {
       return of(res);
    });
  }

  example2(): Observable<any> | any {
     this.example3().pipe(
      catchError(err => {
        return throwError(err);
      })
    ).subscribe(res => {
      return of(res);
    });

  }

  example3() {
    return of('return from example 3');
  }

现在出现错误“无法读取未定义的属性‘管道’”

example3() 正确返回值,但从 example2 值没有返回到示例 1

链接:stackblitz demo

【问题讨论】:

  • example2() 不返回任何内容。
  • example1()也没有
  • @denajan,当一个 observable 依赖另一个时,你必须使用 switchMap
  • 嗨,我从 example1() 和 example2() 返回了值。但仍然没有运气

标签: angular rxjs rxjs6


【解决方案1】:

example1()example2() 函数不返回任何内容。只需添加 return 关键字即可返回您的 Observables。

【讨论】:

    【解决方案2】:

    您无需订阅 example1()、example2()、example3()。
    异步回调方法中的返回 subscribe 不是函数的返回。

      example1(): Observable<any> | any {
        console.log('1');
        return this.example2().pipe(
          catchError(err => {
            return throwError(err);
          })
        );
      }
    
      example2(): Observable<any> | any {
        console.log('2');
        return this.example3().pipe(
          catchError(err => {
            return throwError(err);
          })
        );
      }
    
      example3() {
        console.log('3');
        return of('return from example 3');
      }
    

    StackBlitz

    更新(2019 年 3 月 15 日) 根据您的评论,代码应为:

    export class AppComponent {
      response;
      private init$: Observable<any>;
    
      public ngOnInit() {
        //get Data from remote
        this.example3().subscribe(value => {
          //Do primary somethimg with result
          let calcVal = value *2;
          // Do remote something with data
          this.example2(calcVal).subscribe(newValue => {
            // Result with updated data
            console.log(newValue);
            this.response = newValue;
          });
        });
      }
    
      // Async do something with data
      example2(value: number): Observable<string>{
        return of('Value is: ' + value);
      }
    
      // Async get data
      example3(): Observable<number> {
        console.log('3');
        return of(3);
      }
    
    }
    

    StackBlitz

    或者用switchMap:

    export class AppComponent {
      response;
      private init$: Observable<any>;
    
      public ngOnInit() {
        let obs = this.example3().pipe(switchMap(val => this.example2(val)));
        obs.subscribe(result => this.response = result);
      }
    
      // Async do something with data
      example2(value: number): Observable<string>{
        return of('Value is: ' + value);
      }
    
      // Async get data
      example3(): Observable<number> {
        console.log('3');
        return of(3);
    
    }
    

    StackBlitz

    【讨论】:

    • 感谢@lvanes 的宝贵回复。它工作正常,但我的情况有点不同。我在 sample2 函数中计算一些东西,其中传入值来自 sample3(),最终值将转到sample1() 函数。请看stackblitz stackblitz.com/edit/angular-eyz2j7
    • @debanjanMal 你的 example2 计算应该是异步的吗? Updated example
    • @lvanes 是的,它是异步数据,但计算部分应该发生在 example2() 中,因为这对所有人都很常见。我想我可以使用 switchMap
    • switchMap 可能会对您有所帮助。但是你需要吗?如果第一个 Observable 流被多次调用 next() ,它将用于组合两个 Observable 和自动取消订阅。答案(更新后)不适合你吗? (About switchMap)
    • @lvanes 任何建议。这是强制性的,所有计算部分都将在 example2() 中进行