简体   繁体   English

在 Angular 中使用 RXJS 从单个组件上的多个服务中获取数据

[英]Fetching data from multiple service on single component using RXJS in angular

I have two services with我有两项服务

ser1. SER1.

  getdata1() {
    this.http.get<{message:string,Data1:any}>('http://localhost:3000/api/1')
      .pipe(map((data1)=>{
        return Data1.Data1.map(data=>{
          return  {
            id: data._id,
            data1Title:data1.data1Title,
          }
        })
      })).subscribe((data1) => {
        this.data1=data1
        this.serv1Subject.next([...this.data1])
      })
  }

  getData1Listener() {
    return this.serv1Subject.asObservable()
  }

ser2 SER2

  getdata2() {
    this.http.get<{message:string,Data2:any}>('http://localhost:3000/api/2')
      .pipe(map((data2)=>{
        return Data2.Data2.map(data=>{
          return  {
            id: data._id,
            data2Title:data2.data1Title,
          }
        })
      })).subscribe((data2) => {
        this.data2=data2
        this.serv2Subject.next([...this.data2])
      })
  }

  getData2Listener() {
    return this.serv2Subject.asObservable()
  }

Now on componentx i need to fetch the data1 and data2 in nginit and after the data is available need to perform an functionY现在在 componentx 上,我需要在 nginit 中获取 data1 和 data2,在数据可用后需要执行一个函数Y

How can i use subscribe to trigger an functionY?我如何使用订阅来触发功能Y?

In componentx.ts在 componentx.ts

ngOnInit() {
    this.Service1OberableSubject = this.serv1.getData1Listener().subscribe((data1) => {
      this.data1 = data1;
    })
    this.Service2OberableSubject = this.serv2.getData2Listener().subscribe((data2) => {
      this.data2 = data2;
    })
    this.serv1.getdata1()
    this.serv2.getdata2()
  }

Possibly something like this.可能是这样的。 Use tap to tap into the response and do anything needed.使用tap进入响应并执行任何需要的操作。 And forkJoin will merge the response and give it in an array, the first index will the be response of the first observable that was passed in. forkJoin将合并响应并将其放入数组中,第一个索引将是传入的第一个 observable 的响应。

getdata1() {
    this.http.get<{message:string,Data1:any}>('http://localhost:3000/api/1').pipe(
        map((data1)=>{
            return Data1.Data1.map(data=>{
              return {
                id: data._id,
                data1Title:data1.data1Title,
              }
            })
        }),
        tap((data1)=>{
            //save to data1 if needed
            this.serv1Subject.next([...this.data1]))
        })
    )
}

getdata2() {
    this.http.get<{message:string,Data2:any}>('http://localhost:3000/api/2').pipe(
        map((data2)=>{
            return Data2.Data2.map(data=>{
                return  {
                    id: data._id,
                    data2Title:data2.data1Title,
                }
            })
        }),
        tap((data2)=>{
            //save to data2 if needed
            this.serv2Subject.next([...this.data2]))
        })
    )
}


forkJoin(
    getdata1(),
    getdata2()
).subscribe((x:any[])=>this.functionY(x));
  
functionY([a, b]){
    console.log({a: a,b: b});
}

Here's an example of how you can have if implemented:这是一个示例,说明如果实施,您将如何拥有:

import { zip } from 'rxjs';
import { first } from 'rxjs/operators';

ngOnInit() {

  this.serv1.getdata1()
  this.serv2.getdata2()

  zip(this.serv1.getData1Listener(), this.serv2.getData2Listener())
  .pipe(first())
  .subscribe(([data1, data2]) => {
     this.data1 = data1;
     this.data2 = data2;

     functionY(data1, data2)
  })

}

You can use forkJoin from rxjs .您可以使用forkJoinrxjs

import { forkJoin } from 'rxjs';

component.ts组件.ts

ngOnInit() {
  forkJoin([this.serv1.getData1Listener(), this.serv2.getData2Listener()]).subscribe(data => {
    this.data1 = data[0];
    this.data2 = data[1];

  });
}

forkJoin should be the best operator in this scenario. forkJoin 应该是这个场景中最好的操作符。 It is equally important to understand other higher order operators, this will help to know when to use those.了解其他高阶运算符同样重要,这将有助于了解何时使用它们。 For eg例如

concatMap — helps to map observables in sequence while waiting for previous observable to complete. concatMap — 有助于在等待前一个 observable 完成时按顺序映射 observable。 The best use case would be a sequential form save.最好的用例是顺序表单保存。

mergeMap — helps mapping of observables running in parallel. mergeMap — 帮助映射并行运行的 observable。 All the previous Observables are kept alive.所有之前的 Observable 都保持活动状态。

switchMap — switchMap is the way to go if we want to cancel previous subscriptions. switchMap — 如果我们想取消以前的订阅,switchMap 是要走的路。 Type-ahead feature is best implemented using switchMap combined with deboundTime() and distinctUntilChanged().最好使用 switchMap 结合 deboundTime() 和 distinctUntilChanged() 来实现预输入功能。

exhaustMap — used for ignoring newly emitted values till ongoing observable is complete. ExhaustMap — 用于忽略新发出的值,直到正在进行的 observable 完成。 Best used when we are saving data on click of a button, which has a probability of being clicked multiple times.当我们点击按钮保存数据时最好使用,它有可能被多次点击。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM