在调用其他订阅之前等待 API 调用或订阅 finish/return(等待)

wait for API call or subscription to finish/return before calling other subscriptions (await)

我在 chrome 的网络选项卡中收到一堆失败的 API 呼叫。这是因为我可以在瀑布上看到我的“创建客户”订阅尚未完成执行,然后“创建地址”和“创建联系人 phone 号码”都 运行 并且没有等待它完成。

我使用 await....toPromise() 函数寻找答案,但现在已弃用并且在我的场景中不起作用。

我如何在 rxjs/angular 的较新版本中实现它?

// API call for create customer
this.userService.createCustomer(customer).subscribe({
  next: (customerResult: Customer) => {
    const createContactAddress =
      customerAddress !== undefined
        ? this.userService.createContactAddress(
            customerResult.partyNumber,
            customerAddress.toJson()
          )
        : of(undefined);
    const createContactEmail =
      email !== undefined
        ? this.userService.createContactPhoneEmail(
            customerResult.partyNumber,
            email
          )
        : of(undefined);
    const createContactPhoneNumber =
      phone !== undefined
        ? this.userService.createContactPhoneEmail(
            customerResult.partyNumber,
            phone
          )
        : of(undefined);

    createContactAddress
      .pipe(combineLatestWith(createContactEmail, createContactPhoneNumber))
      .subscribe({
        next: () => {
          this.isSaving = false;
          this.modalSaved.emit(customerResult);
        },
        error: () => {
          this.isSaving = false;
          this.closeModal();
        }
      });
  },
  error: () => {
    this.isSaving = false;
    this.closeModal();
  }
});

}

您可以使用 switchMap/mergeMap 来执行 subscribe 中的逻辑,而不是嵌套订阅

// API call for create customer
this.userService
  .createCustomer(customer)
  .pipe(
    switchMap((customerResult: Customer) => {
      const createContactAddress =
        customerAddress !== undefined
          ? this.userService.createContactAddress(
              customerResult.partyNumber,
              customerAddress.toJson()
            )
          : of(undefined);
      const createContactEmail =
        email !== undefined
          ? this.userService.createContactPhoneEmail(
              customerResult.partyNumber,
              email
            )
          : of(undefined);
      const createContactPhoneNumber =
        phone !== undefined
          ? this.userService.createContactPhoneEmail(
              customerResult.partyNumber,
              phone
            )
          : of(undefined);

      return createContactAddress.pipe(
        combineLatestWith(createContactEmail, createContactPhoneNumber)
      );
    })
  )
  .subscribe({
    next: () => {
      this.isSaving = false;
      this.modalSaved.emit(customerResult);
    },
    error: () => {
      this.isSaving = false;
      this.closeModal();
    }
  });

What I understood is,

  1. you want to call this.userService.createCustomer
  2. After completion of [1] you want to perform these three createContactAddress, createContactEmail, createContactPhoneNumber
  3. After completion of [1] and [2] you want to complete the stream.

根据我的理解,我提供我的解决方案

this.userService
  .createCustomer(customer)
  .pipe(
    switchMap((customerResult: Customer) =>
      forkJoin([
        this.createContactAddress(customerAddress, customerResult),
        this.createContactEmail(email, customerResult),
        this.createContactPhoneNumber(phone, customerResult),
      ]).pipe(map((result) => [customerResult, ...result]))
    ),
    catchError((err) => {
      this.isSaving = false;
      this.closeModal();
    })
  )
  .subscribe({
    next: (customerResult, addressResult, emailResult, phoneResult) => {
      this.isSaving = false;
      this.modalSaved.emit(customerResult);
    },
    error: () => {
      this.isSaving = false;
      this.closeModal();
    },
  });


createContactAddress(customerAddress, customerResult): Observable<any> {
  return customerAddress !== undefined
    ? this.userService.createContactAddress(
        customerResult.partyNumber,
        customerAddress.toJson()
      )
    : of(undefined);
}

createContactEmail(email, customerResult): Observable<any> {
  return email !== undefined
    ? this.userService.createContactPhoneEmail(
        customerResult.partyNumber,
        email
      )
    : of(undefined);
}

createContactPhoneNumber(phone, customerResult): Observable<any> {
  return phone !== undefined
    ? this.userService.createContactPhoneEmail(
        customerResult.partyNumber,
        phone
      )
    : of(undefined);
}