获取最新的扫描累积结果,而不是重复进行?

时间:2018-12-11 09:07:28

标签: angular rxjs observable

下面的代码执行以下操作:

  1. 通过调用backendService加载一整套书籍。 backendServiceReplaySubject(10)的形式返回结果,每个发射值返回600本书,大约8次。以大块形式返回结果的原因是为了快速向用户提供一些数据,因为每个大块都需要花费一秒钟以上的时间来检索。
  2. 然后loadBooks方法选择书名,并将发出的数组累积到一个完整的书列表中。
  3. 图书清单组件使用findBooksByFilter方法。它返回一个可观察到的过滤后的书名数组。

我的问题是,应避免每次我调用方法scan时重复执行findBooksByFilter操作。真的,我只对_books$可观察到的最新累积价值感兴趣。

export class BookService  {

  constructor(private backendService: BackendService) {
    this.loadBooks();
  }

  private _bookCategoryRid = '6662c0f2.ee6a64fe.25cm75kl2.m4fvotr.e7t9hb.l892ddpqqi2971ldvj4ea';

  private _books$ = new Observable<string[]>();

  private loadBooks(): void {
    this._books$ = this.backendService.getBookDtosByCategory(this._bookCategoryRid).pipe(
      scan<AssetSearchResultItem[], string[]>((acc, curr) => {
        const v = curr.map(val => val._name);
        return acc.concat(v);
      } , [])
    );
  }

  public getBooks(): Observable<string[]> {
    return this._books$;
  }

  public findBooksByFilter(searchPhrase: string): Observable<string[]> {
    if ( !searchPhrase.trim() || searchPhrase.length < 1) {
      return this._books$;
    }
    return this._books$.pipe(
      map(
        books => {
          console.log(books);
          return books.filter(
            book => ( term.indexOf(searchPhrase) >= 0));
          }
    ));
  }


}

1 个答案:

答案 0 :(得分:0)

您似乎希望拥有一种“缓存”机制,以避免调用后端API并重新降低每个订户的结果。

一种实现方法是使用shareReplay(1)运算符。它缓冲参数值中定义的尽可能多的通知,并在订阅时立即将其发送给每个新订阅者。将该值设置为1时,它将发送最后收到的通知,使其成为一种“缓存”(以前是操作员的名称,但是实际的缓存具有更多的配置选项)。

使用您的代码,它将是:

this._books$ = this.backendService.getBookDtosByCategory(this._bookCategoryRid).pipe(
  scan<AssetSearchResultItem[], string[]>((acc, curr) => {
    const v = curr.map(val => val._name);
    return acc.concat(v);
  } , []),
  shareReplay(1)
);