[英]How to avoid Observable inside Observable
我有一个带有 http 请求的服务,它返回我的标题的 Observables
服务.ts
get(sort: string): Observable<Response> {
return this.http.get<any>(this.url, {...});
})
delete(id) {
return this.http.delete(`${this.url}/${id}`, {...});
}
在我的组件中,我有一个 function 从服务获取请求中设置this.headlines
。 它看起来像这样:
interface IRes {
searches: {
label: string,
id: number,
value: string,
...
}
}
headlines = [];
loadHeadlines() {
this.service.get(data).subscribe((res: IRes) => this.headlines= res.headlines);
}
问题是有时我会收到带有空 label 的标题并且不需要显示它们,因此我需要对其进行过滤并发送.delete() 请求以获取此标题。 我试过这样的事情(想法是在订阅之前添加.pipe
并在另一个subscribe
中调用。)类似的东西
loadHeadlines() {
this.service.get(data)
.pipe(
map(res: IRes => {
res.headlines.filter(headline => !!headline.label.trim())
.forEach(headline => this.service.delete(headline.id).subscribe())
})
)
.subscribe((res: IRes) => this.headlines= res.headlines);
}
但不确定这是个好主意。 这里哪种方法更好?
您可以使用 RxJS switchMap
运算符到 map 从一个可观察对象到另一个,然后forkJoin
function 组合多个可观察对象。 我还使用了iif
(with of
) function 来检查是否有要删除的空headline
。
但我不明白你目前使用的条件。 在 rest 上调用delete
时,您似乎正在删除所有具有空label
属性的headline
元素。 所以本质上你是在所有有效元素上调用delete
。 也许它必须调整。
尝试以下
import { iif, forkJoin, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
loadHeadlines() {
this.service.get(data).pipe(
switchMap((res: IRes) => {
const emptyHeadlines = res.headlines.filter(headline => !headline.label.trim()); // <-- all headlines with empty labels
const deletes$ = forkJoin(
emptyHeadlines.map(headline => this.service.delete(headline.id))
).pipe(
map(_ => ({ // <-- map back to return only the headlines with defined `label`
...res,
headlines: headlines.filter(headline => !!headline.label.trim())
}))
);
return iif(
() => !!emptyHeadlines.length,
deletes$, // <-- execute delete only if there are empty headlines
of(res) // <-- if not forward the response
);
})
).subscribe(
(res: IRes) => this.headlines = res.headlines,
(error: any) => console.log(error)
);
}
好吧, ..headline.label.trim()
绝对不是一个好主意,因为 double !
将删除所有不为空的标题。 还有map
应该是一个tap
。
所以对于完整的 pipe:
this.service.get(data).pipe(
map(res => res.headlines)
tap(headlines => headlines.filter(headline => !headline.label.trim()).forEach(
headline => this.service.delete(headline.id)
)),
map(headlines => headlines.filter(headline => !!headline.label.trim())),
).subscribe(headlines => this.headlines= headlines);
在真实场景中,我将把它留给后端处理。 但是,这是强烈的观点,因为这里没有客观的对/错。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.