RxJS |如何使用concatMap在管道中捕获并失败?

时间:2019-06-25 13:34:38

标签: angular rxjs concatmap

我正在尝试使用concatMap来允许我按顺序运行请求,而不必在视觉上订阅我发送的每个请求。

一切正常,但是当出现错误时,它将继续通过管道运行,这是我不希望的。

如果失败,我只想能够取消所有请求,停止运行并显示一些内容。我已经尝试过catchError,但这似乎不起作用/无法完成我想要的事情。

以这个例子为例...

我想重设用户密码,密码重设后我想POST/password/resets端点,然后我想自动登录用户,因此我想发布到/auth/login,然后我想吸引用户GET - /user,以便在整个应用程序中使用它。如果请求在任何阶段失败。我想停止管道并抛出一个通用错误,该错误显示在问题的底部。

this.userService.resetPassword(password)
.pipe(concatMap(() => this.authService.login(user.email, password)))
.pipe(concatMap(() => this.userService.me()))
.subscribe((user: User) => {
    this.userService.setUser(user);
});

示例:

this.userService.resetPassword(password)
.pipe(concatMap(() => this.authService.login(user.email, password)))
<-- IF IT FAILS ON THE ABOVE / ANY REQUEST I WANT TO STOP ALL REQUESTS AND SHOW NOTIFICATION -->
.pipe(concatMap(() => this.userService.me()))
.subscribe((user: User) => {
    this.userService.setUser(user);
});

下面的代码段是我想在出错时运行的内容-

this.notificationService.notify('Unable to reset password, please try again.');

3 个答案:

答案 0 :(得分:0)

可以将catchError添加到相同级别的concatMap吗? (例如:)

// also no need to put pipe for each piping. You can add a single one
this.userService.resetPassword(password)
  .pipe(concatMap(() => this.authService.login(user.email, password)),
        concatMap(() => this.userService.me()),
        catchError(err => throwError('error'))
  .subscribe((user: User) => {
    this.userService.setUser(user);
});

此catch错误应该在途中捕获任何错误,然后将其扔回去。如果我没错的话。如果将其捕获在concatMap内部,则可以解决innerObservable,但外部将继续进行。因此,您需要停止高层以使其发挥所需的作用。

答案 1 :(得分:0)

使用管道和rxjs运算符的方式使其无法捕获。 catchError运算符可以捕获其所在管道中的异常。

您可以更正并再试一次吗?

yourCall().pipe(
    concatMap(() => otherCall()),
    concatMap(() => otherCall()),
    catchError( error => handleError())
).subscribe(result => doWhatYouWant());

答案 2 :(得分:-1)

您可以使用catchError https://blog.angular-university.io/rxjs-error-handling/ 另外,您可以在单个pipe()内链接调用,而不必重复执行。

类似的东西

this.userService.resetPassword(password)
.pipe(
    concatMap(() => this.authService.login(user.email, password).pipe(
        map(() => this.userService.me()),
        catchError(error => doSomething)))),
    ).subscribe((user: User) => {
    this.userService.setUser(user);
});