【问题标题】:problems handling asynchronism and observables in Angular在 Angular 中处理异步和可观察的问题
【发布时间】:2021-06-01 09:30:34
【问题描述】:

在我的项目中,我需要根据某些日期(月和年)计算一些数据,因此一旦我在数组“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)
    )

}

问题是在循环内部我发出了返回 observables 的 http.get 请求并且我失去了控制

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

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

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

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

我尝试使用 async/await 并使用具有相同结果的 Promise

我更新了服务

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;
    }
  )
}
}

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

有什么想法吗?

谢谢

【问题讨论】:

  • 当你循环时不要订阅,而是把你所有的http调用放到一个数组中,然后使用forkJoin这个数组来一次得到所有的响应。

标签: angular async-await angular-observable


【解决方案1】:

问题是在循环内部我发出了返回 observables 的 http.get 请求并且我失去了控制

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

而且由于我需要按顺序计算值以在图表中显示它们,所以这是不值得的,我不知道如何离开这里。有什么想法吗?

解决办法是:

1.将请求数组转换为异步响应数组(可观察对象或承诺)

2. 等待所有请求都得到解决并使用forkJoin()Promise.all() 收到所有响应

3.处理所有响应。

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 => {
       //...
    })
  })
}

更新:

对于更新后的问题,如果您从服务中返回承诺,那么...

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 => {
       //...
    })
  })
}

【讨论】:

  • 您好,这项工作与一个请求一起工作,但我需要执行另一个请求以根据日期计算花药值如何按顺序链接多个请求?
  • 你可以在 Promise.all() 之前链接请求,它会等到所有链接的请求都被解决
  • 但是对于 observables 例如,在响应常量中,我为每个礼节做一个返回,所以我有一个 Observable[] 但我需要为每个礼节返回 4 个响应。那么我怎么能得到这个常数呢?
猜你喜欢
  • 2019-01-11
  • 1970-01-01
  • 2018-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-28
  • 2019-05-25
  • 2020-08-10
相关资源
最近更新 更多