仅当填充indexedDb表时,元件中的Angular 载荷数据

btqmn9zl  于 2022-12-09  发布在  IndexedDB
关注(0)|答案(1)|浏览(192)

在我的服务我有这个:

synchronizeCitiesOnLogin() {
    ....
    this.getCitiesFromApi().subscribe(
      cities => {
        cities.map((city) => {
            this.addCityToIndexedDb(city);
        });
      }
    );
  }
  getCitiesFromApi() {
    ....
    return this.apiClient.get(url, { })
      .pipe(
        map((response: any) => response.data ),
        catchError(errorRes => {
          return throwError(errorRes);
        })
      );
  }
  addCitiesToIndexedDb(city) {
    this.cityTable
      .add(city)
      .then(async () => {
        const allItems: CityModel[] = await this.cityTable.toArray();
      })
      .catch(e => {
        alert('Error: ' + (e.stack || e));
      });
  }
    getData(): Promise<any> {
        return this.getDataFromIndexedDb()
    }
    private async getDataFromIndexedDb() {
       ...
       ... 
       return mydata
    }

在我的组件中:

ngOnInit() {
    this.myService.getData().then(data => {
      this.worldCities= data;
    });
}

因为我从API接收了很多数据,所以需要一些时间来将它们全部保存在IndexedDB中。当我加载页面时,“fruits”对象将为空,因为数据尚未保存在IndexedDB中...如果我添加一个2-3秒的settimeout,它是有效的,但可以肯定的是,这应该是一个更好的解决方法。有人能帮助我吗?谢谢

jmp7cifd

jmp7cifd1#

您可以考虑将BehaviorSubject添加到myService

private synchronized$ = new BehaviorSubject(false);

此后,您需要以某种方式捕获cities插入到indexeddb中的完成情况,其内容可能类似于

import { from } from 'rxjs';

synchronizeCitiesOnLogin() {
  this.getCitiesFromApi().pipe(
    switchMap((cities) => combineLatest(
      cities.map(city => from(this.cityTable.add(city)))
    )),
    tap(() => {
      this.synchronized$.next(true);
    })
  ).subscribe()
}

然后,您可以通过执行以下操作来确保数据在访问之前已同步:

getData(): Promise<any> {
    return this.synchronized$.pipe(
      filter(synchronized => synchronized),
      first(),
      switchMap(() => from(this.getDataFromIndexedDb()))
    ).toPromise();
 }

上面的内容当然可以变得更易读,因为我强烈建议使用完整的RxJs,以避免通过使用ngx-indexed-db在可观察性和承诺性API之间不断切换。

相关问题