首页 > 解决方案 > 如何在 Observable 中避免 Observable

问题描述

我有一个带有 http 请求的服务,它返回我的 Headlines 的 Observables

服务.ts

get(sort: string): Observable<Response> {
    return this.http.get<any>(this.url, {...});
})

delete(id) {
  return this.http.delete(`${this.url}/${id}`, {...});
}

在我的组件中,我有一个this.headlines从服务获取请求设置的功能。它看起来像这样:

interface IRes {
  searches: {
    label: string,
    id: number,
    value: string,
    ...
  }
}
headlines = [];

loadHeadlines() {
  this.service.get(data).subscribe((res: IRes) => this.headlines= res.headlines);
}

问题是有时我会收到带有空标签的标题并且不需要显示它们,因此我需要对其进行过滤并发送 .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);
}

但不确定这是个好主意。这里哪种方法更好?

标签: javascriptangulartypescriptrxjs

解决方案


你可以使用 RxJSswitchMap操作符从一个 observable 映射到另一个 observable,并forkJoin使用函数来组合多个 observable。我还使用iif(with of) 函数来检查是否有headline要删除的空 s。

但我不明白你目前使用的条件。似乎您在调用其余元素时正在删除所有headline具有空属性的元素。所以本质上你是在调用所有有效的元素。也许它必须调整。labeldeletedelete

尝试以下

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)
  );
}

推荐阅读