Angular 中处理异步和可观察对象的问题

problems handling asynchronism and observables in Angular

在我的项目中,我需要根据一些日期(月和年)计算一些数据,所以一旦我在数组“this.etiquetasEjeX”中有了日期。我循环它们以像这样计算组件中的数据

ngOnInit() {
this.getGastadoRealizado();
console.log('GraficaComponent-ngOnInit()-this.gastadoRealizado: ',this.gastadoRealizado);
}

getGastadoRealizado(){
let valorAnterior:number=0;
let valorEnMesYAño:number=0;

for(let etiqueta of this.etiquetasEjeX){   
 this.dataService.getGastadoRealizadoEnMesYAño(
   this.proyectoId,
   getMonthNumber(etiqueta.slice(0,etiqueta.length-4)),+etiqueta.slice(-4),
   this.acumular)
  .pipe(
    tap(item=>console.log(`GraficaComponent-ngOnInit()-getGastoRealizado() de ${etiqueta} : 
   ${item}`))
  )
  .subscribe(
    item=>{
      valorEnMesYAño=item;
      this.gastadoRealizado.push(valorAnterior+valorEnMesYAño);
      valorAnterior+=valorEnMesYAño;
      this.gastadoRealizadoAcumulado += valorEnMesYAño;
    }
  )
}

}

在我的服务中,我有调用服务器的方法

getGastadoRealizadoEnMesYAño(proyectoId: string, mes:number, año:number, acumular: 
  boolean):Observable<number>{
  return this.http.get<number> 
(`${this.urlProyecto}/proyectos/${proyectoId}/mes/${mes+1}/anio/${año}/acumular/${acumular}/gastado`)
    .pipe(          
      catchError(this.handleError)
    )

}

问题是在循环内,我使 http.get 请求 return 可观察对象并且我失去了控制

当我登录控制台时,我看到了这个

我按我需要的顺序查看我的日期,因此循环以相同的顺序遍历它们

但是当我记录响应时,顺序是另一个完全随机的

而且由于我需要按顺序遍历并计算值以在图表中显示它们,这不值得,而且我不知道如何离开这里

我试过 async/await 使用 promises 得到相同的结果

我更新了服务

async getGastadoRealizadoEnMesYAño(proyectoId: string, mes:number, 
año:number, acumular: boolean){
return await this.http.get<number> 
(`${this.urlProyecto}/proyectos/${proyectoId}/mes/${mes+1}/
anio/${año}/acumular/ 
${acumular}/gastado`).toPromise();
}

以及组件中的调用

async getGastadoRealizado(){
let valorAnterior:number=0;
let valorEnMesYAño:number=0;

for(let etiqueta of this.etiquetasEjeX){
  
this.dataService.getGastadoRealizadoEnMesYAño(
 this.proyectoId,
 getMonthNumber(etiqueta.slice(0,etiqueta.length4)),
 +etiqueta.slice(-4),this.acumular)
  .then(
    item=>{
      valorEnMesYAño=item;
      this.gastadoRealizado.push(valorAnterior+valorEnMesYAño);
      valorAnterior+=valorEnMesYAño;
      this.gastadoRealizadoAcumulado += valorEnMesYAño;
    }
  )
}
}

但是我每次运行顺序都不一样

有什么想法吗?

谢谢

The issue is that inside the loop for I make http.get requests that return observables and I loose the control

每个异步调用可能需要不同的时间量,因此可能不会 return 以相同的顺序响应。

And since I need to go through and calculate the values in that order to show them in a graph, this is not worth it and I do not know how to get out of here. Any idea Please?

解决方法是:

1.Convert 请求数组到异步响应数组(可观察对象或承诺)

2.Wait 直到所有请求都得到解决并且所有响应都使用 forkJoin()Promise.all()

收到

3.Process 所有回复。

getGastadoRealizado() {
  // ...

  const responses = this.etiquetasEjeX.map(etiqueta => {  // Converted for loop to map
    return this.dataService.getGastadoRealizadoEnMesYAño(
      // ...
    ).pipe(tap(item => {
      // ...
    }))
  })

  forkJoin(responses).subscribe(items => {
    items.forEach(item => {
       //...
    })
  })
}

更新:

对于更新后的问题,如果您return 承诺服务,那么...

getGastadoRealizado() {
  // ...

  const responses = this.etiquetasEjeX.map(etiqueta => {  // Converted for loop to map
    return this.dataService.getGastadoRealizadoEnMesYAño(
      // ...
    )
  })

  Promise.all(responses).then(items => {
    items.forEach(item => {
       //...
    })
  })
}