typescript Angular RXJS优化嵌套订阅

chhkpiq4  于 2023-05-08  发布在  TypeScript
关注(0)|答案(2)|浏览(160)

嘿,我有一个更新函数调用嵌套订阅,相互依赖,只是在成功的父调用订阅内部的

updateSelectedScopes() {
    let params: any = {
     userInterface: this.userInterface,
     targetId: this.assessmentId,
     targetUserId: this.currentUser['userId'],
    };
    this.lockService.acquireLock(params).subscribe(lockingDetails => {
     if (lockingDetails) {
       let payload = this.consolidatedPayload
       this.assessmentService.updateSelectedScopes(payload).subscribe(res => {
         if (res) {
           this.releaseLock(
             this.assessmentId,
             this.currentUser['userId'],
             this.userInterface
           );
           this.modalService.dismissAll();
           if ((this.assessmentStatus === this.appConstants.CERTIFIED ||
             this.assessmentStatus === this.appConstants.UN_CERTIFIED ) ||
             this.assessmentStatus === this.appConstants.ASSESSMENT_FLAGGED) {
             this.assessmentService.initiateWorkflow(this.assessmentId).pipe(take(1)).subscribe(() => {
                 this.router.navigate([this.appConstants.VIEW_ASSESSMENT_URI], { skipLocationChange: true, queryParams: { 'assessmentId': this.assessmentId,  assessment: this.assessmentDetailsObj['assessmentName'], 'updateFlag': true } });
             }, (error) => {
               this.modalService.dismissAll();
               this.openAlert(error.error);
             });
         } else {
             this.router.navigate([this.appConstants.VIEW_ASSESSMENT_URI], { skipLocationChange: true, queryParams: { 'assessmentId': this.assessmentId, assessment: this.assessmentDetailsObj['assessmentName'], 'updateFlag': true } });
         }
         }
       }, error => {
         this.modalService.dismissAll();
         this.releaseLock(
           this.assessmentId,
           this.currentUser['userId'],
           this.userInterface
         );
         this.openAlert(error.error);
       });
     }
   }, error => {
     this.openLockDialog(
       error.error,
       this.currentUser['userId'],
       this.assessmentId,
     );
   })
 }

我可以用switchMap/mergeMap/flatMap优化这个函数(使用嵌套订阅),以避免这种丑陋的嵌套订阅吗?任何帮助都会很棒

t2a7ltrp

t2a7ltrp1#

通常在类似的情况下,您应该使用concatMap运算符连接一系列Observables。
concatMap确保一旦上游Observable通知了什么,下面的Observable就会被“执行”。
在你的逻辑中,似乎也有一些“非React性”逻辑,特别是在错误的情况下。要管理这种情况,可以使用catchError运算符。
其思路如下

// you have 3 functions that return observables
const doStuff: (param: string) => Observable<string>;
const doSomethingElse: (param: string) => Observable<string>;
const doSomeMoreStuff: (param: string) => Observable<string>;

doStuff("a param").pipe(
    concatMap((result) => {
        return doSomethingElse(result).pipe(
            catchError((error) => {
                // do something with error that may occur in doSomethingElse
                return of("")
            })
        )
    }),
    concatMap((result) => {
        return doSomeMoreStuff(result).pipe(
            catchError((error) => {
                // do something with error that may occur in doSomeMoreStuff
                return of("")
            })
        )
    }),
    catchError((error) => {
        // do something with error that may occur in doStuff
        return of("")
    })
)
.subscribe()

在您的情况下,您的代码可以或多或少地像这样重构(我没有一个工作示例,代码有点复杂,所以我无法测试以下片段,因此可能会有错误-这只是为了给予一个想法)

this.lockService.acquireLock(params).pipe(
    concatMap(lockingDetails => {
        if (lockingDetails) {
            let payload = this.consolidatedPayload
            return this.assessmentService.updateSelectedScopes(payload).pipe(
                catchError(
                    (error) => {
                        this.modalService.dismissAll();
                        this.releaseLock(
                            this.assessmentId,
                            this.currentUser['userId'],
                            this.userInterface
                        );
                        this.openAlert(error.error);
                        return of(null)
                    }
                )
            )  
        }
        return of(null)
    }),
    concatMap(res => {
        return this.assessmentService.updateSelectedScopes(payload).pipe(
            catchError(
                (error) => {
                    this.modalService.dismissAll();
                    this.openAlert(error.error);
                    return of(null)
                }
            )
        )
    }),
    catchError(
        (error) => {
            this.openLockDialog(
                error.error,
                this.currentUser['userId'],
                this.assessmentId,
            );
        }
    )
 )
 .subscribe()

This article可以为类似的用例给予一些灵感。

sigwle7e

sigwle7e2#

试试这个:

updateSelectedScopes() {
    let params: any = {
        userInterface: this.userInterface,
        targetId: this.assessmentId,
        targetUserId: this.currentUser['userId'],
    };
    this.lockService.acquireLock(params).pipe(
        forkJoin(this.assessmentService.updateSelectedScopes()),
        tap(() => {
            this.releaseLock(
                this.assessmentId,
                this.currentUser['userId'],
                this.userInterface
            );
            this.modalService.dismissAll();
        })
    ).subscribe(res => {
        if (res) {
            if ((this.assessmentStatus === this.appConstants.CERTIFIED ||
                this.assessmentStatus === this.appConstants.UN_CERTIFIED) ||
                this.assessmentStatus === this.appConstants.ASSESSMENT_FLAGGED) {
                this.assessmentService.initiateWorkflow(this.assessmentId).pipe(take(1)).subscribe(() => {
                    this.router.navigate([this.appConstants.VIEW_ASSESSMENT_URI], { skipLocationChange: true, queryParams: { 'assessmentId': this.assessmentId, assessment: this.assessmentDetailsObj['assessmentName'], 'updateFlag': true } });
                }, (error) => {
                    this.modalService.dismissAll();
                    this.openAlert(error.error);
                });
            } else {
                this.router.navigate([this.appConstants.VIEW_ASSESSMENT_URI], { skipLocationChange: true, queryParams: { 'assessmentId': this.assessmentId, assessment: this.assessmentDetailsObj['assessmentName'], 'updateFlag': true } });
            }
        }
    }, error => {
        this.modalService.dismissAll();
        this.openLockDialog(
            error.error,
            this.currentUser['userId'],
            this.assessmentId,
        );
    });
}

相关问题