当前位置: 首页 > 知识库问答 >
问题:

如何避免可观测中的可观测

夏高朗
2023-03-14

我有一个带有http请求的服务,它返回我的标题的可观察到的内容

servise.ts

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

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

在我的组件中,我有一个函数从service get Request设置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()请求。我尝试了类似的方法(想法是在subscribe之前添加.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);
}

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

共有2个答案

堵宏毅
2023-03-14

嗯,!!headline.label.trim()绝对不是一个好主意,因为双会删除所有非空的标题。此外,映射应该是点击

因此对于完整的管道:

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

在实际场景中,我会让后端处理这个问题。但是tbh,这是非常固执己见的,因为这里没有客观的对错。

司马耘豪
2023-03-14

您可以使用RxJSswitchmap运算符将一个可观察对象映射到另一个可观察对象,并使用forkjoin函数组合多个可观察对象。我还使用iif函数检查是否有任何要删除的空headline

但我不明白你现在用的是什么条件。您似乎正在删除所有headline元素,并带有空的label属性,同时对其余元素调用delete。因此,您实际上是对所有有效元素调用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.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)
  );
}
 类似资料:
  • 我目前在Android和Kotlin上使用RxJava,但我有一个问题,如果不使用toBlocking(),我无法解决。 我在员工服务中有一个方法,它返回一个可观察的 这一切都很好,因为每当员工发生变化时,这个可观察对象就会发出新的员工列表。但是我想从员工那里生成一个PDF文件,这显然不需要每次员工更改时都运行。另外,我想从PDF生成器方法返回一个可完成的对象。我想在PDF中添加一个标题,然后遍历

  • 使用rxjsv6 所以我有多个我想要跟踪/观察的变量,当它们中的任何一个发生变化时,触发一个可观察对象来调用一个API,该API然后根据这些变量更新其他内容。 我想我可能会在上触发一个事件来强制可观察对象做一些事情,但它不会根据我想要的返回结果 例如。 然而,在可观测数据上没有订阅方法。我试图修改我的另一个观察值(这是可行的)

  • 我正在将angular 2组件转换为使用异步数据源。 我有一个<代码> 这会导致错误: 找不到类型为“object”的不同支持对象“[object]”。NgFor只支持绑定到数组之类的可重用文件。 我试过

  • 我有一个可观察的对象,它从数据库游标的快速流中生成数据。我希望以每秒x项的速度限制输出。到目前为止,我一直在使用文档中所述的调用堆栈阻塞: 这很好,但出于好奇,是否有更好的方法使用背压来处理此问题? Tks公司

  • 我希望能够等待一个可观察的时间,例如。 天真的尝试会导致等待立即解析,而不会阻止执行 编辑:我的全部预期用例的伪代码是: 我知道我可以将其他代码移动到另一个单独的函数中,并将其传递到subscribe回调中,但我希望能够避免这种情况。

  • 类定义为: 我继续创建对象: 使用以下工具进行检查: 打印: 但是在html模板中使用可以观察到: 引发: 如何解决这个问题?这里是Stackblitz项目的链接: https://stackblitz.com/edit/Angular-ivy-isebs7?file=src%2fapp%2fapp.component.ts