асинхронное манипулирование данными в Angular - PullRequest
0 голосов
/ 05 марта 2020

Я действительно новичок в этом, и у меня проблемы с манипулированием данными в интерфейсе приложения, которое я разрабатываю.

У меня есть две функции, называемые «getTipoEtapas ()» и «getEtapasporTransfo», которые используют два сервиса для возврата данных бэкэнда и назначения их переменным.

У меня есть третьи функции, которые инициировать нажатие кнопки в файле HTML. Этот вызывает четвертую функцию, которая делает некоторые другие вещи.

Проблема в том, что в четвертой функции я получаю значения emptys (data5, data6, data7). Я думал, что это была асинхронная проблема, поэтому я решил начать использовать обещания. Но я повторяю это, я действительно новый разработчик, поэтому я попытался решить его, и не получилось.

Извините за мой плохой Engli sh.

это код:

getTipoEtapas(){
  this.tipoEtapaService.getTipoEtapas().subscribe(tipoEtapa=>{
    this.data6=tipoEtapa;      
  })
}

getEtapasporTransfo(id:number){
  this.etapaService.getEtapasPorIdTransfo(id).subscribe(etapa=>{
    this.data5=etapa;
  })
}

onRowClicked(row){
  this.data2=row;
  const promesa=new Promise((resolve,rejected)=>{
    this.getEtapasporTransfo(this.data2.idTransfo)
    this.getTipoEtapas();  
    resolve('Resolved');
  });
  promesa.then(()=>{
  this.asignarEtapaTransfo();
  })
}

asignarEtapaTransfo(){
  console.log(this.data5);
  console.log(this.data6);
  console.log(this.data7);

  this.data5.forEach((e,i)=>{
    this.data6.forEach((e,j)=>{
      if(this.data5[i].idTipoEtapa==this.data6[j].idTipoEtapa)
      {
          this.data7[i].nombreEtapa=this.data6[j].nombreEtapa;
      }
    });

    this.data7[i].dateIni=this.data5[i].dateIni;
    this.data7[i].dateFin=this.data5[i].dateFin;
    this.data7[i].tiempoParc=this.data5[i].tiempoParc;
    this.data7[i].tiempoFin=this.data5[i].tiempoFin;   
  });
}

Ответы [ 2 ]

0 голосов
/ 05 марта 2020

Ваша проблема в том, что внутри вашего обещания вы не дожидаетесь завершения двух наблюдаемых. Вы настраиваете их обоих, а затем немедленно возвращаете разрешенное обещание.

Я бы порекомендовал использовать Rx JS до конца, а не комбинировать наблюдаемые и обещания.

Использовать forkJoin запускать несколько наблюдаемых вместе и возвращать объединенный результат, когда они завершены.

data2;
data5;
data6;
data7;

getTipoEtapas(): Observable<any> {
  return this.tipoEtapaService.getTipoEtapas().pipe(
    tap(tipoEtapa => this.data6 = tipoEtapa)
  )
}

getEtapasporTransfo(id:number): Observable<any> {
  return this.etapaService.getEtapasPorIdTransfo(id).pipe(
    tap(etapa => this.data5 = etapa)
  );
}

onRowClicked(row) {
  this.data2 = row;
  forkJoin([
    this.getEtapasporTransfo(this.data2.idTransfo),
    this.getTipoEtapas()
  ]).subscribe(() => {
    this.asignarEtapaTransfo()
  });    
}

asignarEtapaTransfo(){
  console.log(this.data5);
  console.log(this.data6);
  console.log(this.data7);

  this.data5.forEach((e,i)=>{
    this.data6.forEach((e,j)=>{
      if(this.data5[i].idTipoEtapa==this.data6[j].idTipoEtapa)
      {
          this.data7[i].nombreEtapa=this.data6[j].nombreEtapa;
      }
    });

    this.data7[i].dateIni=this.data5[i].dateIni;
    this.data7[i].dateFin=this.data5[i].dateFin;
    this.data7[i].tiempoParc=this.data5[i].tiempoParc;
    this.data7[i].tiempoFin=this.data5[i].tiempoFin;   
  });
}

Сохранение состояния в наблюдаемой цепочке

Мой пример выше почти такой же, как ваш, за исключением меня используя forkJoin для ожидания завершения наблюдаемых.

onRowClicked можно упростить, передав результат forkJoin в asignarEtapaTransfo.

onRowClicked(row) {
  forkJoin({
    data5: this.etapaService.getEtapasPorIdTransfo(row.idTransfo),
    data6: this.tipoEtapaService.getTipoEtapas()
  }).subscribe(result => {
    this.asignarEtapaTransfo(result.data5, result.data6);
  });    
}

asignarEtapaTransfo(data5, data6) {
  // ...
}
0 голосов
/ 05 марта 2020

Вы можете использовать asyn c для достижения. Я просто привожу пример для понимания, и вы можете вносить изменения в зависимости от ваших требований. Вы можете сделать async функцию, которая возвращает обещание, и вы должны использовать awai t в вызываемой функции.

public async callFn1(): Promise<any> {
        let results: any[] = [];
        const somePromise = new Promise((resolve, reject) => {
                    //Perform some operations and get the results
                    resolve(results);
                });

        })
        console.log(results);
        return somePromise;
    }

    public async callFn2(): Promise<void> {
        let results: any[] = await test.callFn1(); // Here test is the object
        console.log(typeof results);
        results.forEach((obj)=>console.log(obj['Some Key']));

    }
}
...