【问题标题】:How can I make sure all my observables have completed before showing a toast message?在显示 toast 消息之前,如何确保我的所有 observables 都已完成?
【发布时间】:2019-08-17 02:09:17
【问题描述】:

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

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

  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。

【问题讨论】:

  • 您可以将 observable 更改为 promise,然后等待响应。然后完成您的通话。

标签: angular typescript rxjs observable rxjs5


【解决方案1】:

您需要使用 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);
});

[“你好”、“世界!”、“再见”、“世界!”]

好的?

【讨论】:

  • 不确定这会有什么帮助。如果deliveryPreferencesService.save 失败,我不想打电话给saveAutoEnroll
【解决方案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)

【讨论】:

  • 这和我需要的很接近,但是this.deliveryPreferencesService.saveAutoEnroll可以在没有this.deliveryPreferencesService.save的情况下调用。
  • 不,只有在调用 deliveryPreferencesService.save(accountPreferenceChanges) 之后才会调用 this.deliveryPreferencesService.saveAutoEnroll。如果没有调用deliveryPreferencesService.save(accountPreferenceChanges),就不会调用deliveryPreferencesService.save(accountPreferenceChanges)。
  • 它们将被严格一致地调用
  • 我在之前的评论中的意思是在我的场景中,如果autoEnrollPreferenceChanges.length 大于零并且accountPreferenceChanges.length 等于零,则可以单独调用this.deliveryPreferencesService.saveAutoEnroll
  • @broke,你可以从 iif 开始,比如 iif(condition, save(), of(undefined)) 然后 switchMapsaveAutoEnroll
【解决方案3】:

对不起,我有。您可以通过使用 async\await 和 Promise 来做到这一点。现在它应该适用于您的方案。

  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 中的 async/await https://tutorialedge.net/typescript/async-await-in-typescript-tutorial/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-14
    • 1970-01-01
    相关资源
    最近更新 更多