конвертировать в методологию rx js - PullRequest
0 голосов
/ 27 апреля 2020

Я хочу преобразовать следующие 2 метода в методологию rx js. Как я могу это сделать. Второй метод зависит от результатов первого.

export class EntityStorage {
  private entitiesStore: Map<string, any[]> = new Map<string, any[]>();

  constructor(private apiService: ApiService) {}

  loadAllEntity(key: string, httpParams: HttpParams): void {
    this.apiService.getEntities(key, httpParams).subscribe(
      (entities) => {
        this.entitiesStore.set(key, entities);
      },
      (error) => {
        console.error(error);
      },
      () => {}
    );
  }

  getStoreWithKey(key: string): any[] {
    return this.entitiesStore.get(key);
  }
}

Ответы [ 2 ]

0 голосов
/ 27 апреля 2020

Я бы сделал это следующим образом:

export class EntityStorage {
  private setEntities = new Subject<[string, any[]]>();
  private entitiesStore = new ReplaySubject<Map<string, any[]>>(1)

  constructor(private apiService: ApiService) {

    this.setEntities.pipe(
      scan((entityMap, [key, entities]) => {
        entityMap.set(key, entities);
        return entityMap;
      }, new Map<string, any[]>())
    ).subscribe(this.entitiesStore)

  }

  loadAllEntity(key: string, httpParams: HttpParams): void {
    this.apiService.getEntities(key, httpParams).subscribe(
      (entities) => {
        this.setEntities.next([key, entities]);
      },
      (error) => {
        console.error(error);
      },
      () => {}
    );
  }

  getStoreWithKey(key: string): any[] {
    return this.entitiesStore.pipe(
      map(entityMap => entityMap.get(key)), 
      filter(entity => !!entity), // optional, prevent emissions until key loaded.
      distinctUntilChanged() // optional. prevents subscribers from receiving updates about different keys.
    );
  }
}

в основном вы используете частный локальный субъект для запуска обновлений в теме воспроизведения вашей карты и используете сканирование для его обновления.

если вы хотите, можете даже переместить загрузку в поток, что даст более точный контроль над загрузкой, ie, не вызывая загрузку объекта дважды для одного и того же ключа (если это возможно в вашем приложении), дайте мне знать, если это необходимо .

0 голосов
/ 27 апреля 2020

Не проверено, но должно работать.

Обратите внимание, что абоненты будут излучать после каждого вызова loadAllEntity, поэтому рассмотрите возможность использования take(1), чтобы игнорировать дальнейшие обновления.

export class EntityStorage {
    private $entitiesStore = new ReplaySubject<Map<string, any[]>>();
    private entitiesStore: Map<string, any[]> = new Map<string, any[]>();

    constructor(private apiService: ApiService) {}

    loadAllEntity(key: string, httpParams: HttpParams): void {
        this.apiService.getEntities(key, httpParams).subscribe(
            (entities) => {
                this.entitiesStore.set(key, entities);
                this.$entitiesStore.next(this.entitiesStore);
            },
            (error) => {
                console.error(error);
            },
            () => {}
        );
    }

    getStoreWithKey(key: string): Observable<any[]> {
        return this.$entitiesStore.pipe(
            map((entitiesStore) => entitiesStore.get(key))
        );
    }
}
...