Избегайте вложенного вызова подписки

У меня есть кнопка, нажатие на нее вызовет сервисный вызов. Наконец, я хочу сообщить пользователю по электронной почте. Электронная почта будет отправлена ​​другим звонком в службу поддержки.

public submitForm = (data, selected = {} ) => {
    console.info(data);
    this.service['submit'].post({body: data}).subscribe(
    () => { null },
    error => {
       console.info(error);
    };
    () => {
         // second subscribe
        this.service['email']['post']({ body: theForm.value }).subscribe(
        () = > {
           // data processing
         }
       );
     }
     );}

Вы видите, что это вложенная подписка. Я использую angular 5 и rxjs 5.5. Как этого избежать?

Обновлено:

К комментарию я добавил сервисный код

public readonly service: SwaggerService

На самом деле все службы находятся в веб-API asp.net, например

[HttpPost]
[Route("email")]
public ActionResult postEmail([FromBody]EmailBody email)
{}
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
0
105
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете использовать switchMap, чтобы избежать вложенной подписки, например:

public submitForm = (data, selected = {} ) => {
  console.info(data);
  this.service['submit'].post({body: data})
      .switchMap(() => {
        return this.service['email']['post']({ body: theForm.value })
                  .catch(err => {
                    //handle your error here

                    //HERE YOU NEED TO DO YOUR SELF; MAKE SURE TO RETURN AN OBSERVABLE FOR HERE.
                    //I ON RXJS 6.4; So I am not sure what is `of` operator in rxjs 5.5
                    //I guss it is Observable.of
                    return Observable.of(err);
                  });
      })
      .catch(err => {
        //handle your error here

        //HERE YOU NEED TO DO YOUR SELF; MAKE SURE TO RETURN AN OBSERVABLE FOR HERE.
        //I ON RXJS 6.4; So I am not sure what is `of` operator in rxjs 5.5
        //I guss it is Observable.of
        return Observable.of(err);
      })
      .subscribe((resultOfSecondCall) => {
        //do your processing here...
        console.info(resultOfSecondCall);
      });

   }

Значит, при первом вызове нет обработки ошибок?

Bigeyes 17.07.2019 01:56

@Bigeyes Если хотите, вы можете использовать оператор catch rxjs для обработки ошибки. Используйте оператор catch во внешнем наблюдаемом. Точно так же вы можете использовать оператор catch во внутреннем наблюдаемом.

user2216584 17.07.2019 01:57

Можете ли вы обновить код, чтобы я мог лучше понять его?

Bigeyes 17.07.2019 01:59

@Bigeyes Обновлен код. Пожалуйста, смотрите комментарий в коде.

user2216584 17.07.2019 02:06

На самом деле у меня есть еще одна подписка, стоит ли мне использовать еще одну карту switchMap?

Bigeyes 17.07.2019 15:08

Если еще один вызов API и это зависит от предыдущего ответа API, тогда да, вы можете добавить столько switchMap, сколько хотите.

user2216584 17.07.2019 15:14

не могу найти of оператора

Bigeyes 18.07.2019 13:12

@Bigeyes, какую версию rxjs вы используете? Если на rxjs 5, то попробуйте импортировать of вот так: import 'rxjs/add/observable/of';

user2216584 18.07.2019 14:21

Я бы поступил иначе. Вы не опубликовали свой код service, поэтому трудно сказать вам, точно, как это сделать. Я сделаю предположение, что ваш служебный код ничего не делает, кроме как делает http вызов на сервер (и, следовательно, возвращает обещание/что-то ожидаемое)

await this.service['submit'].post({body: data});
await this.service['email']['post']({ body: theForm.value });

Использование rxjs по сравнению со стандартными HttpClient/Promises, похоже, не дает здесь никакой пользы. Единственные реальные требования, по-видимому, заключаются в том, что вам нужно выполнить первый вызов (успешно), прежде чем вы отправите электронное письмо. Я бы просто сделал две строки кода, используя await, вместо того, чтобы связывать здесь некоторые наблюдаемые.

В качестве примечания: чтобы await выполнить HttpClient вызов, вы должны сначала преобразовать его в обещание. ИЭ: this.httpClient.post(url, data).toPromise();

Я обновил сервис, дайте мне знать, если возникнут вопросы.

Bigeyes 17.07.2019 01:46

Это не сервисный код. Неясно, относится ли ваш service к типу SwaggerService, но мы понятия не имеем, что делает ваш метод в указанном сервисе.

mwilson 17.07.2019 01:49

Сервисный код слишком длинный. Сожалею об этом. И обязательно ли нужен сервисный код? Потому что я видел много подобных вопросов без обслуживания, но все же получил ответы.

Bigeyes 17.07.2019 01:57

Другие вопросы по теме