RxJS with Angular 双向绑定在catchError中输入多次

RxJS with Angular Two-way binding enter multiple times in catchError

我有一项服务可以将项目存储在会话存储中,并带有到期日期。当我检索一个项目时,如果过期日期,服务 return 空值:

保存物品的方法:

private saveSessionData<T>(key: string, value: T) {
    const now = new Date();
    const item = {
      value: value,
      expiry: now.getTime() + 15 * 60000 // 15 minutes from now
    }
    sessionStorage.setItem(key, JSON.stringify(item));
  }

检索项目的方法:

private getSessionData<T>(key: string): T | null {
    const itemStr = sessionStorage.getItem(key);
    if(!itemStr) return null;
    const item = JSON.parse(itemStr);
    const now = new Date();
    if (now.getTime() > item.expiry) {
      sessionStorage.removeItem(key);
      return null;
    }
    return item.value;
  }

在我的控制器中,我通过将它们放在 Observable 上来访问其中一个值,例如:

const value$ = of(this.storageService.getSessionData<string>('value'))
        .pipe(
          catchError(err => {
            console.log('The session is expired');
            // ... open a modal and route the user to the home
            return err;
          })
        );

然后我将它显示在我的视图中:

{{(value$ | async)}}

一旦我的存储数据过期,我想要的是打开一个模式并将用户路由到另一个页面(这就是我在 catchError().

中所做的

问题是,当我的数据实际过期时,在控制台中我有多个日志,这意味着我在 catchError() 中输入了多次,这是一个问题,因为我的 openModal 函数不是幂等的(所以它打开多个次导致糟糕的用户体验):

console.log :

The session is expired
The session is expired
The session is expired
The session is expired
The session is expired

我怎样才能将其更改为仅调用错误函数一次?

我试图在我的检索数据函数中使用 throws new Error('session expired') 而不是 return null; 并在我的控制器中放置一个 try() catch() 块,但结果相同。

有没有人知道如何只捕获我的错误一次?

据我所知,函数 getSessionData 没有任何异步,您可以放弃整个 of/pipe 块并用一个简单的 if/else 块替换它。如果我遗漏了什么,请发表评论。

如果您在模板中有多个 value$ | async,您最终会得到多个订阅!!!

您可以应用 share() 运算符来确保只使用一个订阅:

const value$ = of(this.storageService.getSessionData<string>('value')).pipe(
  share(), 
  catchError(err => {
    console.log('The session is expired');
  })
);