RxJS subscribe inside subscribe with actions on error

爱⌒轻易说出口 提交于 2019-12-23 22:20:09

问题


I have code with subscribe inside 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);
    }
);

How can I optimize it in RxJS 5?


回答1:


Please don't use subscribe inside another subscribe. Using native RxJS operators, there is better way around this which will be:

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);
    },
  );

This way you only have one subscribe method to handle last remaining result if you want to.

Keep in mind that catchError() inside pipe will be trigerred if exception is fired prior to it anywhere. If exception is handled already, by the handler, same exact exception will not trigger other catchError() twice.



来源:https://stackoverflow.com/questions/54090015/rxjs-subscribe-inside-subscribe-with-actions-on-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!