我有一个 Angular 应用程序,它具有持久性存储和存储项的密钥列表。我想在应用程序启动时将已知键的值从持久存储异步加载到内存中,以便在应用程序运行时可以同步访问它们。所以我创建了一个 Observable,它遍历键列表的所有元素并附加一个管道,它应该获取每个元素的值并移交键和值的组合,因此我可以将它们存储在缓存中。应该捕获在持久存储中找不到值的情况。不幸的是,这仅适用于其中一个键。然后外部 Observable 意外完成。
通过查看日志,我可以看到,外部 Observable 正确地迭代了键列表的三个元素并运行了 switchMap()。但是只有一个值从持久存储中提取出来,并且在 localStorageService.get()-Observable 完成第一个元素之后,from-Observable 完成。
日志显示了这一点:
- from() $.next => (2) ["authorizationDataIdToken", 1]
- switchMap(): 键:authorizationDataIdToken
- from() $.next => (2) ["_isAuthorized", 0]
- switchMap(): 键: _isAuthorized
- from() $.next => (2) ["userData", 0]
- switchMap():键:用户数据
- 来自() $.complete
- localStorageService.get(userData) $.next => [object Object]
- from() - 在 switchMap $.next => (2) ["userData", "[object Object]"] 之后
- OIDC 存储:缓存键:userData,值:[object Object]
- localStorageService.get(userData) $.complete
- from() - 在 switchMap $.complete 之后
- OIDC 存储:随时可用。
这是加载到缓存功能的代码:
private prepareForUsage() {
// Take each element from the securely-stored-keys-list,
// get their values from the secured storage and put them into the cache.
from(Object.entries(this.keysStoredSecurely)).pipe(
log('from()'),
// At this point, we got the key and want to load the value from the local storage.
// But we want to have both, key and value afterwards.
switchMap(([key, protectionLevel]) => {
console.log('switchMap(): key: ', key);
// Here we try to fetch the value for the key via local storage service.
return this.localStorageService.get(key, true).pipe(
log(`localStorageService.get(${key})`),
// Because the item we want to access might not exist yet, we could get an error, that we want to catch.
catchError((error, _) => {
if (isDevMode()) { console.warn(`${error}, key: ${key}`); }
return of(undefined);
}),
// Here we have the value for the key and we want to combine both and return it.
map(value => [key, value])
);
}),
log('from() - after switchMap'),
).subscribe({
// Put each item in the cache.
next: ([key, value]) => {
if (key === undefined || value === undefined) {
if (isDevMode()) { console.log(`OIDC Storage: Key or value missing. key: ${key}, value: ${value}`); }
} else {
if (isDevMode()) { console.log(`OIDC Storage: Cache key: ${key}, value: ${value}`); }
sessionStorage.setItem(key, value);
}
},
error: (error) => {
if (isDevMode()) { console.error(`OIDC Storage: ${error}`); }
},
// Declare the storage as ready for usage.
complete: () => {
if (isDevMode()) { console.log('OIDC Storage: ready for use.'); }
this.isReadyForUsage.next(true);
}
});
}
这是本地存储服务的 get() 函数的签名:
get(key: string, encrypted: boolean = false): Observable<string>
我希望对 from-Observable 发出的每个元素都执行本地存储服务的 get() 函数的调用,但是我可以看到它只调用了一次并且不知道我做错了什么。