RxJS内部订阅,对错误采取行动

时间:2019-01-08 10:39:29

标签: angular typescript rxjs rxjs5

我在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 :(得分:3)

请不要在另一个订阅中使用订阅。使用本机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()两次。