Angular 在可观察对象内的角度异步调用

Angular 在可观察对象内的角度异步调用,angular,asynchronous,rxjs,observable,Angular,Asynchronous,Rxjs,Observable,我有一个函数来控制项目的过期日期。 在这个函数中,我创建了一个可观察项来检查项目是否是新的。 如果它是新的,它会像预期的那样工作,但是当一个公司试图获得一些补充数据来定义它的到期日期是否是它工作不好的时候 如果对单个项进行调用,它可以正常工作,但是当我尝试用多个项填充表时,它返回未定义项 我认为这是一个异步调用的问题。订阅者在为表中的下一项进行新调用之前,不会等待内部httprequest完成 1-函数,用于调用以获取过期日期并设置正确的状态 /* ValueGetter para mostr

我有一个函数来控制项目的过期日期。 在这个函数中,我创建了一个可观察项来检查项目是否是新的。 如果它是新的,它会像预期的那样工作,但是当一个公司试图获得一些补充数据来定义它的到期日期是否是它工作不好的时候

如果对单个项进行调用,它可以正常工作,但是当我尝试用多个项填充表时,它返回未定义项

我认为这是一个异步调用的问题。订阅者在为表中的下一项进行新调用之前,不会等待内部httprequest完成

1-函数,用于调用以获取过期日期并设置正确的状态

 /* ValueGetter para mostrar en la tabla si la droga está vencida o vigente */
      ctlVigencia(params){
        let message: string;   
        this.ds.ctlVencimientoDroga(params.data._id, params.data.informacion.fecha.vencimientoCertificado, null)
        .subscribe(res=> {
          console.log(res);

          if(res.fAsignada == null){
            message= 'No deterninado'
          } else {
            let now = moment(new Date());
            if (res.fAsignada > now ) {
              message= 'Vigente'
            } else {
              message= ('Vencida')
            }
          }
        })
        return message
      };
2返回过期日期值的函数

  /*Control vencimiento droga */
    ctlVencimientoDroga(idSelected: string, vencimientoCertificado: Date, modeForm?: string){
      let retesteos: Retesteo[];
      const resObs= Observable.create((observer:Observer<{[key: string]: any}>) =>{
        if (modeForm == 'nuevo'){
          observer.next({fAsignada: vencimientoCertificado})
          observer.complete();
        } else{
          this.rs.dataRetesteo.subscribe(res=>{ 
            retesteos= res;
            if (retesteos && retesteos.length == 0) {
              if(vencimientoCertificado != null) {
                observer.next({fAsignada: vencimientoCertificado});
              } else {
                observer.next(null);
              }
            }
            /* From here and down is where is the problem */
            if (retesteos && retesteos.length > 0){
              let fechaUltimoRetesteoAprobado: Date;
              retesteos.forEach(element => {
                if (element.estado.estado == estadoAprobacion.Aprobado && (fechaUltimoRetesteoAprobado == null || element.fVencimiento > fechaUltimoRetesteoAprobado )){
                  fechaUltimoRetesteoAprobado= element.fVencimiento
                }
              });
              observer.next({fAsignada: fechaUltimoRetesteoAprobado});
            }
            observer.complete(); 
          });
          this.rs.getById(idSelected);
        }
      })
      return resObs;
  }
}

非常感谢您的帮助。

您正在异步操作中为消息赋值,但同步返回消息。尝试修改ctlVigencia以返回一个可观察值,并对ctlVencimientoDroga的响应使用map


希望它能有所帮助

我会重写几乎所有的内容,以利用运算符

  ctlVigencia(params){  
     // use map operator, return observable
    return this.ds.ctlVencimientoDroga(params.data._id, params.data.informacion.fecha.vencimientoCertificado, null)
    .pipe(map(res=> {
      console.log(res);
      if(res.fAsignada == null){
        return 'No deterninado'
      } else {
        let now = moment(new Date());
        if (res.fAsignada > now ) {
          return 'Vigente'
        } else {
          return 'Vencida'
        }
      }
    }));
  };


ctlVencimientoDroga(idSelected: string, vencimientoCertificado: Date, modeForm?: string){
  let retesteos: Retesteo[];
  if (modeForm == 'nuevo') {
    // return mock observable
    return of({fAsignada: vencimientoCertificado});
  }
  // return this observable and use map operator
  return this.rs.dataRetesteo.pipe(
      map(res=> { 
        retesteos = res;
        if (retesteos && retesteos.length == 0) {
          if(vencimientoCertificado != null) {
            return {fAsignada: vencimientoCertificado};
          } else {
            return null;
          }
        } else {
          let fechaUltimoRetesteoAprobado: Date;
          retesteos.forEach(element => {
            if (element.estado.estado == estadoAprobacion.Aprobado && (fechaUltimoRetesteoAprobado == null || element.fVencimiento > fechaUltimoRetesteoAprobado )){
              fechaUltimoRetesteoAprobado = element.fVencimiento
            }
          });
          this.rs.getById(idSelected); // unclear why or when this should happen
          return {fAsignada: fechaUltimoRetesteoAprobado};
        }
      })
  );
}

然后,任何想要从ctlVigencia获得值的人都需要订阅它。

这里的运算符语法是旧的rxjs 5语法,现在它使用.pipemap。。。我也尝试过这个解决方案,但也有同样的问题。我不能订阅cltVigenciaparams,尽管我返回的是可观察的。你说我不能订阅cltVigenciaparams是什么意思?错误是什么?this.rs.getByIDIDDSelected是一个httpRequest,它是在我订阅的服务中启动的,用于将数据存储在变量上,并使dataRetesteo主题发出http响应。如果我不调用函数data Reteeo不会发出任何信息,函数也不会工作。这是一个非常规的设置,但我想你只需要将其移到返回线上方,或者将其放入延迟中,如果你只想在订阅后执行此操作谢谢你的帮助我知道我可以写得更好,我从中学到了很多这但是我已经尝试过了,我得到的错误属性'subscribe'在'params:any=>Observable'类型上不存在,看起来您需要实际调用函数。。。订阅…我正在这样做,但它给出了我发布的错误。我尝试过这个ctlV{return of 2}并尝试订阅ctlV,但它给出了相同的错误
ctlVigencia(params).subscribe(message => console.log(message));
  ctlVigencia(params){  
     // use map operator, return observable
    return this.ds.ctlVencimientoDroga(params.data._id, params.data.informacion.fecha.vencimientoCertificado, null)
    .pipe(map(res=> {
      console.log(res);
      if(res.fAsignada == null){
        return 'No deterninado'
      } else {
        let now = moment(new Date());
        if (res.fAsignada > now ) {
          return 'Vigente'
        } else {
          return 'Vencida'
        }
      }
    }));
  };


ctlVencimientoDroga(idSelected: string, vencimientoCertificado: Date, modeForm?: string){
  let retesteos: Retesteo[];
  if (modeForm == 'nuevo') {
    // return mock observable
    return of({fAsignada: vencimientoCertificado});
  }
  // return this observable and use map operator
  return this.rs.dataRetesteo.pipe(
      map(res=> { 
        retesteos = res;
        if (retesteos && retesteos.length == 0) {
          if(vencimientoCertificado != null) {
            return {fAsignada: vencimientoCertificado};
          } else {
            return null;
          }
        } else {
          let fechaUltimoRetesteoAprobado: Date;
          retesteos.forEach(element => {
            if (element.estado.estado == estadoAprobacion.Aprobado && (fechaUltimoRetesteoAprobado == null || element.fVencimiento > fechaUltimoRetesteoAprobado )){
              fechaUltimoRetesteoAprobado = element.fVencimiento
            }
          });
          this.rs.getById(idSelected); // unclear why or when this should happen
          return {fAsignada: fechaUltimoRetesteoAprobado};
        }
      })
  );
}