3 votes

Les appels de fonctions imbriquées ne fonctionnent pas (problème de flux de code)

J'ai un problème avec mon code :

Le problème est le suivant :

Si le param.qtamodificata == false, le code s'exécute correctement, mais si params.qtamodificata == true ( et qu'il appelle la fonction getQuantities ) il retourne "undefined" à cause de l'appel async...

J'ai besoin de définir le flux de code d'une manière synchrone afin de retourner le résultat seulement après que toutes les procédures aient fini de traiter...

Comment le réparer ?

Merci de soutenir

getOrderRow

public getOrderRow(params): Observable<any>
  {
    //OFFLINE SWITCH OK
    var res = { headers: [], data: [] }

    return Observable.fromPromise(this._WebDBService.sysConfigurazione.toArray().then(
      data => {

        var art = JSON.parse(data[0].ordinidatajson).filter(
          function(itm,index){
            return itm.codart.v === params.codart;
          }
        );

        res.headers = JSON.parse(data[0].ordiniheaderjson);

        if(params.qtamodificata == true)
        {
          this.getQuantities(art[0].codart.v,null,params.udmmodificata, params['qtaord'+ params.udmmodificata]).subscribe(
            qtys =>{
                  art[0].qtaord1.v = qtys.dqta1;
                  art[0].qtaord2.v = qtys.dqta2;
                  art[0].qtaord3.v = qtys.dqta3;

                  res.data = art[0];

                  return res;
                }
              );          
        }
        else
        {
          res.data = art[0];
          return res;
        }                         
      }
    ));
  }

getQuantities

public getQuantities(codart: string, codvar: string, idqta: number, qta: number): Observable<any>{

    return Observable.fromPromise(this._WebDBService.tbArticoli.where({codart: codart}).toArray().then(
      data => 
      {
        console.log('getQuantities');               

        var qtys = {
          dqta1: 0,
          dqta2: 0,
          dqta3: 0
        }

        var a = data[0];

        switch (idqta) {
          case 1:
            qtys.dqta1 = +qta;
            if (a.rapudm12 > 0 && a.codudm2)
              qtys.dqta2 = qta / a.rapudm12;
            if (a.rapudm23 > 0 && a.codudm3)
              qtys.dqta3 = qta / a.rapudm23;
            break;
          case 2:
            qtys.dqta2 = +qta;
            if (a.rapudm12 > 0 && a.codudm1)
              qtys.dqta1 = qta / a.rapudm12;
            if (a.rapudm23 > 0 && a.codudm3)
              qtys.dqta3 = qta / a.rapudm23;
            break;
          case 3:
            qtys.dqta3 = +qta;
            if (a.rapudm23 > 0 && a.codudm2)
              qtys.dqta3 = qta / a.rapudm23;
            if (a.rapudm12 > 0 && a.codudm1)
              qtys.dqta1 = qta / a.rapudm12;
            break;
        }
        return qtys;

      }));    
  }

Appel de fonction

this.orderService.getOrderRow(params, 'test')
          .subscribe(list => {
            console.log('onlineorder3');
            console.log(list);
            console.log('onlineorder3');
}

1voto

devilmaster Points 439

Je vois que vous vous convertissez Promisses a Observables dans ce cas, je pense Promises en collaboration avec async/await rendra votre code à la fois plus facile à séquencer correctement et plus facile à lire et à comprendre. Une version serait :

public async getOrderRow(params): Promise<any> {
    //OFFLINE SWITCH OK
    var res = { headers: [], data: [] }

    var data = await this._WebDBService.sysConfigurazione.toArray();
    var art = JSON.parse(data[0].ordinidatajson).filter(
        function (itm, index) {
            return itm.codart.v === params.codart;
        }
    );

    res.headers = JSON.parse(data[0].ordiniheaderjson);

    if (params.qtamodificata == true) {
        let qtys = await this.getQuantities(art[0].codart.v, null, params.udmmodificata, params['qtaord' + params.udmmodificata]);

        art[0].qtaord1.v = qtys.dqta1;
        art[0].qtaord2.v = qtys.dqta2;
        art[0].qtaord3.v = qtys.dqta3;

        res.data = art[0];

        return res;

    }
    else {
        res.data = art[0];
        return res;
    }
}

public async getQuantities(codart: string, codvar: string, idqta: number, qta: number): Promise<any> {

    let data = await this._WebDBService.tbArticoli.where({ codart: codart }).toArray();
    console.log('getQuantities');
    var qtys = {
        dqta1: 0,
        dqta2: 0,
        dqta3: 0
    }
    // ... Omitted for brevity
    return qtys;
}

Note J'ai utilisé Promise<any> pour les types de retour, je recommanderais à la place de any vous utilisez un type qui décrit réellement le résultat. Par exemple pour getQuantities la valeur de retour devrait probablement être Promise<{dqta1:number, dqta2:number, dqta3:number }> .

0voto

DarioN1 Points 921

J'ai résolu mon problème en utilisant forkJoin et en réécrivant la méthode getOrderRow :

 public getOrderRow(params): Observable<any>
  {
    //OFFLINE SWITCH OK
    var res = { headers: [], data: [] }

    return Observable.forkJoin(
      Observable.fromPromise(this._WebDBService.sysConfigurazione.toArray()),
      this.getQuantities(params.codart, null, params.udmmodificata, params['qtaord' + params.udmmodificata])
    ).map((
      data: any[]) => {      

        var o = {headers: [], data:[]}

        var art = JSON.parse(data[0][0].ordinidatajson).filter(
          function (itm, index) {
            return itm.codart.v === params.codart;
          }
        );

        art[0].qtaord1.v = data[1].dqta1;
        art[0].qtaord2.v = data[1].dqta2;
        art[0].qtaord3.v = data[1].dqta3;

        o.headers = JSON.parse(data[0][0].ordiniheaderjson);
        o.data = art[0];

        return o;
      }
    );

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X