RXJS / Angular阻止多个订户上的多个HTTP

时间:2019-06-12 14:13:51

标签: angular typescript rxjs rxjs6

我有“ mainData”服务,它包含3个部分:

    分页器组件用于切换页面的
  • currentPage。可以随时更新。
  • folders包含当前文件夹中的所有文件夹。有 2 个组件使用此可观察的(文件夹内容列表的类型)
  • files包含当前文件夹中的所有文件。有 3 个组件使用此可观察的(文件夹内容列表的类型)

默认视图是不带文件夹的视图,因此我不想进行不必要的HTTP调用。

public currentPage = new ReplaySubject(1);
public folders: Observable<FLFolder[]>;
public files: Observable<FLFile[]>;

constructor(
  activatedRoute: ActivatedRoute,
  folderService: FolderService,
  fileService: FileService,
) {
  // Populate `this.currentPage`
  activatedRoute.queryParams.pipe(
    take(1),
    //  Wait until end of this sync tick. If no emission is made, it will use default in the next tick.
    takeUntil(timer(1, queueScheduler)),
    defaultIfEmpty<Params>({}),
  ).subscribe(query => {
    if (query.page) {
      this.currentPage = +query.page;
    } else {
      this.currentPage = 1;
    }
  });

  /** This observable is internal, only to be used by `folders` and `files` */
  const folderIDAndPage: Observable<[string, number]> = combineLatest(
    activatedRoute.url.pipe(
      switchMap(segments => folderService.getFoldersFromSegments(segments)),
      distinctUntilChanged(),
    ),
    this.currentPage.pipe(
      distinctUntilChanged(),
    ),
  ).pipe(
    // Prevent repeating HTTP somehow...
    publishReplay(1),
    refCount(),
  );

  this.folders = folderIDAndPage.pipe(
    switchMap(([folderID, page]) => folderService.getFfolders(folderID, page)),
    // Prevent repeating HTTP somehow...
    publishReplay(1),
    refCount(),
  );

  this.files = folderIDAndPage.pipe(
    switchMap(([folderID, page]) => fileService.getFiles(folderID, page)),
    // Prevent repeating HTTP somehow...
    publishReplay(1),
    refCount(),
  );
}

如果没有订阅foldersfiles,则不会建立HTTP。但是,即使只有一个订阅者订阅它们,foldersfiles都会被填充(在进行HTTP调用时)并同时更新。

2 个答案:

答案 0 :(得分:0)

此服务未在此处调用

this.foldersthis.files。这些组件是怎么回事?

也许重构是正确的?如果我不在的话,请原谅我。

我使用吸气剂设置服务:

private _currentUser = new BehaviorSubject<User>({} as User);

然后,您只能通过访问getter从组件中获取它:

public getCurrentUser(): Observable<User> {
    return this._currentUser.asObservable();
}

这样可以更清晰地调用它。

答案 1 :(得分:0)

请您对代码进行以下更改并尝试-

const getFoldersFromSegments$ = activatedRoute.url.pipe(
  switchMap(segments => folderService.getFoldersFromSegments(segments)),
  distinctUntilChanged(),
  publishReplay(1),
  refCount(),
);

/** This observable is internal, only to be used by `folders` and `files` */
const folderIDAndPage: Observable<[string, number]> = combineLatest(
  getFoldersFromSegments$,
  this.currentPage.pipe(
    distinctUntilChanged(),
  ),
).pipe(
  // Prevent repeating HTTP somehow...
  publishReplay(1),
  refCount(),
);

顺便说一句-您在take(1)上使用了activatedRoute.queryParams可观察;这将使您的this.currentPage仅被更改一次。但是你说,

  

可以随时更新

,这不是矛盾吗?还是故意的?