在显示吐司消息之前,如何确保所有可观察物都已完成?

时间:2019-03-26 15:59:49

标签: angular typescript rxjs observable rxjs5

我有一个场景,我必须进行一些api调用,然后显示一些吐司消息,通知用户调用成功还是失败。在下面的代码中,processSaveResponses方法在解析可观察对象之前被调用。 processSaveResponses方法负责显示烤面包消息。我知道这是预期的行为,因为可观察对象是异步的,但是我不知道如何“等待”可观察对象的完成。

deliveryPreferencesService.savedeliveryPreferencesService.saveAutoEnroll方法彼此独立,但是如果deliveryPreferencesService.saveAutoEnroll失败,则不应调用deliveryPreferencesService.save

  private saveChanges(changeSet: DeliveryPreferencesChangeSet) {

    let deliveryPrefernceResult;
    let saveAutoEnroll = true;

    const { accountPreferences: accountPreferenceChanges, autoEnrollPreferences: autoEnrollPreferenceChanges } = changeSet.changes;

    if (accountPreferenceChanges.length) {
      this.deliveryPreferencesService.save(accountPreferenceChanges).
        subscribe(
          () => deliveryPrefernceResult = true,
          () => saveAutoEnroll = false);
    }

    if (autoEnrollPreferenceChanges.length) {
      if (saveAutoEnroll) {
        this.deliveryPreferencesService.saveAutoEnroll(autoEnrollPreferenceChanges).
          subscribe(
            () => console.log('save auto enroll completed'),
            () => saveAutoEnroll = false);
      }
    }

    this.processSaveResponses([{ success: deliveryPrefernceResult }, {success: saveAutoEnroll}]);
  }

这是processSaveResponses的代码:

    if (every(responses, ['success', false])) {
      this.showErrorToastr(this.ALL_CHANGES_FAILURE_MESSAGE);
    }
    else if (every(responses, ['success', true])) {
      this.originalPreferences = cloneDeep(this.currentPreferences);
      this.onChange.next();
      this.showSuccessToastr(this.ALL_CHANGES_SUCCESS_MESSAGE);
    }
    else {
      if ((responses[0] as any).success) {
        this.originalPreferences.accountPreferenceSets = cloneDeep(this.currentPreferences.accountPreferenceSets);
        this.showSuccessToastr(this.DELIVERY_PREFERENCES_SUCCESS_MESSAGE);
        this.showErrorToastr(this.AUTO_ENROLL_FAILURE_MESSAGE);
      } else {
        this.originalPreferences.autoEnrollPreferences = cloneDeep(this.currentPreferences.autoEnrollPreferences);
        this.showSuccessToastr(this.AUTO_ENROLL_SUCCESS_MESSAGE);
        this.showErrorToastr(this.DELIVERY_PREFERENCES_FAILURE_MESSAGE);
      }
    }
  }

任何帮助将不胜感激。我正在使用rxjs版本5.5.2。

3 个答案:

答案 0 :(得分:2)

尝试按此处所述使用switchMap。我想它可以用于您的情况。 https://www.learnrxjs.io/operators/transformation/switchmap.html

this.deliveryPreferencesService.save(accountPreferenceChanges)
  .pipe(
    switchMap(x => this.deliveryPreferencesService.saveAutoEnroll(autoEnrollPreferenceChanges))
  )
  .subscribe(() => {
    // TODO something
  })

在这种情况下,this.deliveryPreferencesService.saveAutoEnroll(autoEnrollPreferenceChanges)仅在成功this.deliveryPreferencesService.save(accountPreferenceChanges)后才会被调用

答案 1 :(得分:0)

您需要使用 zip

import { of, zip } from 'rxjs';



const x1$ = of('Hello');
const x2$ = of('World!');
const x3$ = of('Goodbye');
const x4$ = of('World!');

const subscription = zip(x1$, x2$, x3$, x4$).subscribe( res => {
  console.log(res);
});
  

[“你好”,“世界!”,“再见”,“世界!”

确定

答案 2 :(得分:0)

对不起,我知道了。您可以通过使用带有保证的async \ await来做到这一点。现在,它应该可以根据您的情况运行。

  private async saveChanges(changeSet: DeliveryPreferencesChangeSet) {
    const { accountPreferences: accountPreferenceChanges, autoEnrollPreferences: autoEnrollPreferenceChanges } = changeSet.changes;

    if (accountPreferenceChanges.length) {
      await this.deliveryPreferencesService.save(accountPreferenceChanges).toPromise();
    }

    if (autoEnrollPreferenceChanges.length) {

        await this.deliveryPreferencesService.saveAutoEnroll(autoEnrollPreferenceChanges).toPromise();
    }

    this.processSaveResponses([{ success: true }, {success: true}]);
  }

有关TS中的异步/等待的更多信息 https://tutorialedge.net/typescript/async-await-in-typescript-tutorial/