简体   繁体   English

如何在 Observable 中避免 Observable

[英]How to avoid Observable inside Observable

I have a service with http request which return Observables of my Headlines我有一个带有 http 请求的服务,它返回我的标题的 Observables

servise.ts服务.ts

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

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

and in my component I have a function that set this.headlines from service get request.在我的组件中,我有一个 function 从服务获取请求中设置this.headlines It looks like this:它看起来像这样:

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

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

The problem is that sometimes I receive headline with empty label and don't need to show them, so I need to filter it and send.delete() request for this headlines.问题是有时我会收到带有空 label 的标题并且不需要显示它们,因此我需要对其进行过滤并发送.delete() 请求以获取此标题。 I tried something like this( The idea was to add .pipe before subscribe and call inside another subscribe.) Something like that我试过这样的事情(想法是在订阅之前添加.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);
}

but not sure that it's good idea.但不确定这是个好主意。 Which method would be better here?这里哪种方法更好?

You could use RxJS switchMap operator to map from one observable to another and forkJoin function to combine multiple observables.您可以使用 RxJS switchMap运算符到 map 从一个可观察对象到另一个,然后forkJoin function 组合多个可观察对象。 I've also used iif (with of ) function to check if there are any empty headline s to be deleted.我还使用了iif (with of ) function 来检查是否有要删除的空headline

But I fail to understand the condition you're using at the moment.但我不明白你目前使用的条件。 It seems you're removing all the headline elements with empty label property while invoking delete on the rest.在 rest 上调用delete时,您似乎正在删除所有具有空label属性的headline元素。 So essentially you're calling delete on all the valid elements.所以本质上你是在所有有效元素上调用delete Perhaps it must be adjusted.也许它必须调整。

Try the following尝试以下

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

well, ..headline.label.trim() definitely isn't a good idea, because the double !好吧, ..headline.label.trim()绝对不是一个好主意,因为 double ! will delete all headlines that are NOT empty.将删除所有不为空的标题。 also that map should be a tap .还有map应该是一个tap

so for the complete pipe:所以对于完整的 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);

In a real scenario, i'd leave this to be handled by the backend.在真实场景中,我将把它留给后端处理。 But tbh, this is strongly opinionated, as there is no objective right/wrong here.但是,这是强烈的观点,因为这里没有客观的对/错。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM