RxJS подписаться внутри подписаться с действиями по ошибке - PullRequest
0 голосов
/ 08 января 2019

У меня есть код с subscribe внутри subscribe:

this.http.post('/update1', newData).subscribe(
    (response) => {
        const r = response.json;
        const id = r['id'];
        this.http.post('/update2?id=' + id, newData).subscribe(
            () => {
                this.http.post('/update3?id=' + id, newData).subscribe(
                    () => {
                        console.log('success');
                    },
                    () => {
                        // revert changes made to update2
                        this.http.post('/update2', previousValues).subscribe();
                        // revert changes made to update1
                        this.http.post('/update1', previousValues).subscribe();
                    });
            },
            () => {
                // revert changes made to update1
                this.http.post('/update1', previousValues).subscribe();
            }
        );
    },
    (error) => {
        console.log(error);
    }
);

Как я могу оптимизировать его в RxJS 5?

1 Ответ

0 голосов
/ 08 января 2019

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

this.http
  .post('/update1', newData)
  .pipe(
    map((response) => response.json),
    map((data) => data.id),
    switchMap((id) =>
      this.http.post('/update2?id=' + id, newData).pipe(
        switchMap(() => this.http.post('/update3?id=' + id, newData)),
        catchError((err) => {
          // this catcherror will happen if update3 failes
          return merge(
            // revert changes made to update2
            this.http.post('/update2', previousValues),
            // revert changes made to update1
            this.http.post('/update1', previousValues),
          );
        }),
      ),
    ),
    catchError((err) => {
      // this catcherror will happen if update2 failes
      // revert changes made to update1
      return this.http.post('/update1', previousValues);
    }),
  )
  .subscribe(
    (result) => {
      console.log(result);
    },
    (err) => {
      // this error will happen if an error happens wich is not caught
      console.log(err);
    },
  );

Таким образом, у вас есть только один метод подписки для обработки последнего оставшегося результата, если вы хотите.

Имейте в виду, что catchError() внутри трубы будет срабатывать, если исключение сработало до этого где-либо. Если исключение уже обработано обработчиком, это же точное исключение не вызовет другой catchError() дважды.

...