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');
})
);
我有一项服务可以将项目存储在会话存储中,并带有到期日期。当我检索一个项目时,如果过期日期,服务 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');
})
);