首页 > 解决方案 > 如何将第一个可观察的结果用于下一个可观察的?

问题描述

我有这个方法:

 zip(
  this.$one.getOne(id)
     .pipe(switchMap(oneResult => {
        return this.$two.getTwo(oneResult.id)
      }))
     .pipe(switchMap(twoResult => {
        // Here I Would like to use the **oneResult** as argument to the $three observable too.
        return this.$three.getThree(oneResult.id)
     })),
   this.$four.getFour()
 ).subscribe(zipResult => {
     [getTwoResult, getThreeResult]
 }

如何将$oneObservable 结果传递给$twoObservable 和$hreeobservable?我可以在第一个 switchMap 上得到它。

标签: angularrxjs

解决方案


你一个使用mapswitchMap创建一个“resultSelector”。switchMap有一个 resultSelector 函数,可用于创建相同的效果,但这可能会在 RxJS 的未来版本中被弃用,而不是map像下面的答案所示的那样使用。您将有效地打包oneResulttwoResult放入一个对象或数组中,以便在第二个中使用switchMap。您可以根据需要继续执行此操作。它看起来像这样(我添加了延迟来模拟 API 调用):

import { Component } from '@angular/core';
import { Observable, of, zip } from 'rxjs';
import { map, switchMap, delay } from 'rxjs/operators';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  name = 'Angular';

  getOne(id: string): Observable<string> {
    return of('foo').pipe(delay(1000));
  }

  getTwo(id: string): Observable<string> {
    return of('bar').pipe(delay(1000));
  }

  getThree(id: string): Observable<string> {
    return of('baz').pipe(delay(1000));
  }

  getFour(id: string): Observable<string> {
    return of('foobar').pipe(delay(1000));
  }


  ngOnInit(): void {
    zip(
      this.getOne('foo').pipe(
        switchMap(oneResult =>
          this.getTwo(oneResult).pipe(
            map(twoResult => ({ oneResult, twoResult }))
          )
        ),
        switchMap(oneTwoResult => {
          console.log(oneTwoResult);
          return this.getThree(oneTwoResult.oneResult);
        })
      ),
      this.getFour('foobar')
    )
    .subscribe(result => console.log(result));
  }
}

使用resultSelector功能switchMap

zip(
  this.getOne('foo').pipe(
    switchMap(oneResult =>
      this.getTwo(oneResult),
      (oneResult, twoResult) => ({ oneResult, twoResult })
    ),
    switchMap(oneTwoResult => {
      console.log('oneTwoResult: ', oneTwoResult);
      return this.getThree(oneTwoResult.oneResult)
    })
  ),
  this.getFour('foobar')
)
.subscribe(result => console.log(result));

这是一个StackBlitz,展示了此功能的实际应用。

希望这会有所帮助!


推荐阅读