如何用 Angular 应用程序的异步 Indexed-db 替换同步本地存储
how to replace synchronous local-storage with asynchronous Indexed-db for Angular App
我正在使用本地存储获取数据,如果数据在本地存储上不可用,则调用服务器 API 并将数据添加到存储以供将来使用,然后 return 输入数据。所以下次它将 return 来自存储的数据而不是来自 API 调用的数据。
我有通用功能来完成这项工作,一切正常。
getData(host,url):Observable<any> {
const serverurl = host + url;
const apiname = url.indexOf('?') !== -1 ? url.substring(1, url.indexOf('?')) : url.substring(1, url.length);
const params = url.indexOf('?') !== -1 ? url.substring(url.indexOf('?') + 1, url.length) : '';
var t0 = performance.now();
var result = null ;
result = this.GetStorageEx(apiname, params);
if (result)
{
var t1 = performance.now()
console.log(apiname + ' returned from storage. time taken:' + (t1 - t0) + ' milliseconds.');
return new Observable(observer => {observer.next(result);observer.complete();})
}
else
{
return this.getDataFromServer(serverurl).pipe(map(
result => {
this.UpdateStorageEx(apiname,result, params);
var t1 = performance.now()
console.log(apiname + ' returned from server. time taken:' + (t1 - t0) + ' milliseconds.');
return result;
},
err => {
console.log(err);
}
));
}
}
此处 GetStorageEx 是同步调用,因此如果结果为空,我可以调用服务器 API。
由于本地存储在数据大小方面的限制,我决定使用IndexedDB,但我看到它异步调用获取数据。
所以我的问题是我应该如何修改函数 getData 以使该函数的调用者无需更改并且该函数的行为将保持不变。唯一预期的变化是 GetStorageEx 而不是从本地存储获取,我需要从 IndexedDB 获取它。 (从 IndexedDB return 承诺获取数据)。
您必须使用 RxJs 链接可观察对象:
getData(host,url):Observable<any> {
// stuff
var t0 = performance.now();
this.GetDataFromDb(...).pipe(
switchMap(dbData => {
if(dbData && dbData.length > 0) {
// data found in DB, return it ("of" trick to have the same behavior as the else statement)
return of(dbData)
} else {
// no data in DB, let's call the server
// switch from DB observable to Server observable
return this.getDataFromServer(serverurl).pipe(
tap(serverData => {
this.UpdateDbEx(apiname,result, params).subscribe(); // empty subscribe if writing in DB is async
var t1 = performance.now()
console.log(apiname + ' returned from server. time taken:' + (t1 - t0) + ' milliseconds.');
})
);
}
})
);
我正在使用本地存储获取数据,如果数据在本地存储上不可用,则调用服务器 API 并将数据添加到存储以供将来使用,然后 return 输入数据。所以下次它将 return 来自存储的数据而不是来自 API 调用的数据。
我有通用功能来完成这项工作,一切正常。
getData(host,url):Observable<any> {
const serverurl = host + url;
const apiname = url.indexOf('?') !== -1 ? url.substring(1, url.indexOf('?')) : url.substring(1, url.length);
const params = url.indexOf('?') !== -1 ? url.substring(url.indexOf('?') + 1, url.length) : '';
var t0 = performance.now();
var result = null ;
result = this.GetStorageEx(apiname, params);
if (result)
{
var t1 = performance.now()
console.log(apiname + ' returned from storage. time taken:' + (t1 - t0) + ' milliseconds.');
return new Observable(observer => {observer.next(result);observer.complete();})
}
else
{
return this.getDataFromServer(serverurl).pipe(map(
result => {
this.UpdateStorageEx(apiname,result, params);
var t1 = performance.now()
console.log(apiname + ' returned from server. time taken:' + (t1 - t0) + ' milliseconds.');
return result;
},
err => {
console.log(err);
}
));
}
}
此处 GetStorageEx 是同步调用,因此如果结果为空,我可以调用服务器 API。
由于本地存储在数据大小方面的限制,我决定使用IndexedDB,但我看到它异步调用获取数据。
所以我的问题是我应该如何修改函数 getData 以使该函数的调用者无需更改并且该函数的行为将保持不变。唯一预期的变化是 GetStorageEx 而不是从本地存储获取,我需要从 IndexedDB 获取它。 (从 IndexedDB return 承诺获取数据)。
您必须使用 RxJs 链接可观察对象:
getData(host,url):Observable<any> {
// stuff
var t0 = performance.now();
this.GetDataFromDb(...).pipe(
switchMap(dbData => {
if(dbData && dbData.length > 0) {
// data found in DB, return it ("of" trick to have the same behavior as the else statement)
return of(dbData)
} else {
// no data in DB, let's call the server
// switch from DB observable to Server observable
return this.getDataFromServer(serverurl).pipe(
tap(serverData => {
this.UpdateDbEx(apiname,result, params).subscribe(); // empty subscribe if writing in DB is async
var t1 = performance.now()
console.log(apiname + ' returned from server. time taken:' + (t1 - t0) + ' milliseconds.');
})
);
}
})
);