Angular 中的多个 http.post

multiple http.post in Angular

我正在尝试为数组的每个元素发送一个 http.post 请求,我的方法运行良好,但是当我订阅时,它会针对每个请求执行此操作,如果有人可以帮助我优化它,我将非常感激,这里我留下我的代码片段。

component.ts

saveExclusion() {
this.indForm.value.Centers.forEach(element => {
  for (const days of this.exclusionDays) {
    delete days.horadesde;
    delete days.horahasta;
    delete days.id;
    for (const key in days) {
      if (days[key] === true) {
        days[key] = true;
      }else if (days[key] === false) {
        delete days[key];
      }
    }
  }
  const valueForm = this.indForm.value;
  valueForm.ResourceId = this.idResource;
  valueForm.TimeZoneId = 'America/Santiago';
  valueForm.CenterId = element;
  this.exclusionFunc = false;
  this.apiFca.saveNew(valueForm, this.exclusionDays)
    .pipe(last()).subscribe((res: any) => {
      console.log(res)
      if (res === '200') {
        this.successMessage = true;
        this.exclusionDays = [];
        this.indForm.reset();
        this.ngOnInit();
        setTimeout(() => {
          this.successMessage = false;
        }, 3000);
      }
    }, err => {
      console.log('error', err);
    });
});

}

service.ts

saveNew(exclusionData, daysBlock) {
  let reason = '';
  const dt = new Date();
  const n = dt.getTimezoneOffset();
  const tz = new Date(n * 1000).toISOString().substr(14, 5);
  if (exclusionData.OtherReason) {
    reason = exclusionData.ExclusionReason + ' ' + exclusionData.OtherReason;
  } else {
    reason = exclusionData.ExclusionReason;
  }
  if (exclusionData.ExclusionType !== 'Partial' ) {
    daysBlock = [];
  }
  const data = {Exclusion: new ExclusionClass(
   [],
   reason,
   exclusionData.ExclusionType,
   exclusionData.Repetition,
   exclusionData.CenterId,
   exclusionData.ProfessionalName,
   exclusionData.ResourceId,
   daysBlock,
   exclusionData.TimeZoneId,
   'Exclude',
   exclusionData.Unit,
   exclusionData.ValidFrom + 'T' + exclusionData.ValidTimeFrom + ':00-' + tz,
   exclusionData.ValidTo + 'T' + exclusionData.ValidTimeUntil + ':59.999-' + tz
  )};
  if (exclusionData.CenterId === '') {
    delete data.Exclusion.CenterId;
  }
  return this.http
      .post("url", data)
      .pipe(
        map((res: any) => {
          return res.code;
        })
      );
}

您好,期待您的评论,谢谢。

我对我的 rxjs 知识不是很自信,但看起来,因为 .pipe(last()),你只看了最后一个请求?我建议您仅在所有操作均无误的情况下设置成功,例如

this.apiFca.saveNew(valueForm, this.exclusionDelays)
    .subscribe(
        res => {
            console.log(res);
        },
        err => {
            console.log(err);
        },
        () => {
            this.successMessage = true;
            // etc. etc. etc.
        });

或者可能不使用 this.successMessage 而使用像 this.saveState$ 这样的东西,它将是一个 BehaviorSubject 对象,用 'idle' (或其中的一些枚举)初始化,你的 saveExclusion()功能管理。这样,您的 saveExclusion() 函数的开头就可以

  1. 设置const saveState$ = this.saveState$
  2. 断言 saveState$.getValue() === 'in process' 或者如果不是,就做点什么,
  3. saveState$.next('in process');

您可以将订阅线路更改为

this.apiFca.saveNew(valueForm, this.exclusionDelays)
.subscribe(
    res => {
        if (res !== '200') {
            saveState$.next('unexpected result')
    }   },
    err => {
        console.log(err);
        saveState$.next('error');
    },
    () => {
        if (saveState$.getValue() === 'in process') {
            saveState$.next('success');
    }   }
);

然后您也可以订阅组件的 saveState$(尽管您希望在组件外部提供 saveState$.asObservable(),因此外部代码无法注入值)。这在您的组件初始化中提供了一些优雅的 event-driven 代码:

saveState$.pipe(filter(val => val === 'error'))
.subscribe(functionToTellYourUserThereWasAnError);

// if successful, we want other code to know, but immediately change it back to 'idle' even if other code errors
saveState$.pipe(filter(val => val === 'success')
.subscribe(val => saveState$.next('idle'));

// upon success, reset me
saveState$.pipe(filter(val => val === 'success'))
.subscribe(
    val => {
        this.exclusionDays = [];
        // etc. etc.
        // setTimeout not needed because set to 'idle' in a different thread.
    }
)

此外,我认为您的模板也可以反映和更改 UI 以响应 saveState$ 中的更改,因此您的保存按钮可以 enabled/disabled 基于是否saveState 为 'idle',等等