【问题标题】:How to combine the results of two observable in angular?如何组合两个可观察到的结果?
【发布时间】:2017-08-05 04:43:14
【问题描述】:

如何在angular中合并两个observable的结果?

this.http.get(url1)
    .map((res: Response) => res.json())
    .subscribe((data1: any) => {
        this.data1 = data1;
    });

this.http.get(url2)
    .map((res: Response) => res.json())
    .subscribe((data2: any) => {
        this.data2 = data2;
    });

toDisplay(){
  // logic about combining this.data1 and this.data2;
}

上面是错误的,因为我们不能立即得到data1和data2。

this.http.get(url1)
    .map((res: Response) => res.json())
    .subscribe((data1: any) => {
    this.http.get(url2)
        .map((res: Response) => res.json())
        .subscribe((data2: any) => {
            this.data2 = data2;

            // logic about combining this.data1 and this.data2
            // and set to this.data;
            this.toDisplay();
        });
    });

toDisplay(){
  // display data
  // this.data;
}

我可以在第二个 observable 的 subscribe 方法中组合结果。 但我不确定这是否是实现我的要求的好习惯。

更新:
我发现的另一种方法是使用 forkJoin 组合结果并返回一个新的 observable。

let o1: Observable<any> = this.http.get(url1)
    .map((res: Response) => res.json())

let o2: Observable<any> = this.http.get(url2)
    .map((res: Response) => res.json());

Observable.forkJoin(o1, o2)
  .subscribe(val => {  // [data1, data2]
    // logic about combining data1 and data2;
    toDisplay(); // display data
});

toDisplay(){
  // 
}

【问题讨论】:

标签: javascript angular


【解决方案1】:

编辑 2021:这是一个更新的教程:

https://scotch.io/tutorials/rxjs-operators-for-dummies-forkjoin-zip-combinelatest-withlatestfrom/amp

一个很好的方法是使用 rxjs forkjoin 运算符(包含在 Angular btw 中),这使您远离嵌套的异步函数地狱,您必须使用回调在函数之后嵌套函数。

这里有一个关于如何使用 forkjoin(以及更多)的精彩教程:

https://coryrylan.com/blog/angular-multiple-http-requests-with-rxjs

在示例中,您发出两个 http 请求,然后在 subscribe 胖箭头函数中,响应是一个结果数组,您可以根据需要将它们组合在一起:

let character = this.http.get('https://swapi.co/api/people/1').map(res => res.json());
let characterHomeworld = this.http.get('http://swapi.co/api/planets/1').map(res => res.json());

Observable.forkJoin([character, characterHomeworld]).subscribe(results => {
  // results[0] is our character
  // results[1] is our character homeworld
  results[0].homeworld = results[1];
  this.loadedCharacter = results[0];
});

数组中的第一个元素总是对应于你传入的第一个http请求,以此类推。几天前,我成功地使用了它,同时处理了四个请求,并且效果很好。

【讨论】:

  • 小旁注,它的用法是 forkJoin([character, characterHomeworld]),而不是 Observable.forkJoin([character, characterHomeworld],根据您的文章链接 :)
  • 你可以使用 Observable.forkJoin([character, characterHomeworld]).subscribe([char, charHome]=> { (而不是 results[0]) char.homeworld = charHome; this.loadedCharacter =字符;});这使它更具可读性和更简洁。
【解决方案2】:

我们可以根据需要以不同的方式组合 observables。我有两个问题:

  1. 第一个的响应是第二个的输入:flatMap() 是 适合这种情况。
  2. 两者都必须在继续之前完成:可以根据需要使用 forkJoin()/megre()/concat() 你的输出。

您可以找到上述所有功能的详细信息here。 你可以找到更多可以执行的操作来组合 observables here。

【讨论】:

    【解决方案3】:

    如果它不起作用,请尝试使用 forkJoin,然后尝试一下 combineLatest() 它的作用 - 它在完成流数组之前将流数组中最后发出的值合并为一个。

    Observable.combineLatest(
            this.filesServiceOberserval,
            this.filesServiceOberserval,
            this.processesServiceOberserval,
        ).subscribe(
            data => {
              this.inputs = data[0];
              this.outputs = data[1];
              this.processes = data[2];
            },
            err => console.error(err)
        );
    

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 2019-02-09
      • 2021-10-31
      • 2019-08-18
      • 1970-01-01
      • 2018-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多