下面的代码执行以下操作:
backendService
加载一整套书籍。 backendService
以ReplaySubject(10)
的形式返回结果,每个发射值返回600本书,大约8次。以大块形式返回结果的原因是为了快速向用户提供一些数据,因为每个大块都需要花费一秒钟以上的时间来检索。loadBooks
方法选择书名,并将发出的数组累积到一个完整的书列表中。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));
}
));
}
}
答案 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)
);