如何用Angular App用异步Indexed-db替换同步本地存储

问题描述 投票:0回答:1

我正在使用本地存储来获取数据,如果本地存储上没有可用的数据,则调用服务器API,并将数据添加到存储以供将来使用,然后返回数据。因此下一次它将从存储而不是从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是同步调用,因此如果结果为null,则可以调用服务器API。

由于在数据大小方面对本地存储的限制,我决定使用IndexedDB,但是我看到它的异步调用来获取数据。

因此,我的问题是我应该如何修改getData函数,以使该函数的调用者无需更改,并且此功能的行为将保持不变。只有预期的更改会从本地存储获取,而不是GetStorageEx,我需要从IndexedDB获取它。 (来自IndexedDB的getData返回Promise)。

angular local-storage indexeddb
1个回答
0
投票

您必须使用RxJ链接可观察对象:

 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.');
                           })
                         );
          }
        })
    );
© www.soinside.com 2019 - 2024. All rights reserved.