【发布时间】:2018-07-12 05:17:14
【问题描述】:
我有这个代码:
const id = 1; // id = 2
of([{id: 1, name: 'abc'}]).pipe(
map(items => items.find(item => item.id === id)),
switchMap(item => item ? of(item) : this.makeHttpRequest(id))
);
makeHttpRequest(id: number): Observable<IdNamePair>{}
简而言之,
如果在数组中找到具有特定 id 的对象,则返回 observable of({id: 1, name: 'abc'})
如果在数组中找不到对象,则返回由
返回的可观察对象 this.makeHttpRequest(id) 方法
我想去掉 of(item) 运算符。
此代码有效,但有没有办法不创建新的可观察对象并重用“map()”创建的可观察对象?
编辑:
export class MyService {
private _list = new BehaviorSubject([{id: 1, name: 'abc'}]);
list = this._list.asObservable();
findOne(id: number) {
this.list.pipe(
map(items => items.find(item => item.id === id)),
switchMap(item => item ? of(item) : this.makeHttpRequest(id))
);
}
}
在 Angular 组件中:
export class MyComponent {
item$: Observable<IdNamePair>;
constructor(private service: MyService) {}
ngOnInit() {
this.item$ = this.service.findOne(1); // or (2), id comes from router
}
}
【问题讨论】:
-
我认为没有。
switchMap作为参数传入的函数必须返回一个 Observable。在itemnull 的情况下,这是由this.makeHttpRequest(id)执行的。在另一种情况下,您必须找到一种方法来创建 Observable,而of似乎是最自然的方法。 -
如果我理解的话,你想实现一种缓存。因此,如果您已经拥有该元素,则无需获取它。在这种情况下,从“cahce”创建您的可观察对象可能不是最好的方法。您的事件应该是您传递的 ID,而不是您尝试过滤的列表。如果我在正确的方向,我可以帮助你实施
-
你有两个
of()s,那么你想去掉哪个? -
没有
of也可以。例如from加上filter,但你会等待完成,例如使用toArray。关键是,解决方案会更复杂,也不一定优雅。 -
@martin,switchMap 运算符中的第二个“of()”。我正在寻找类似“else()”运算符的东西。有一个“iif()”运算符,但这并不能解决问题。