订阅内部订阅:如何等待两者在单一订阅中完成

发布于 2025-02-13 16:23:28 字数 569 浏览 1 评论 0原文

我是RXJ的新手,我有一件事想实现,但我不知道如何实现。

我有2个API电话。但是第二个取决于第一个值。问题在于我想用一份订阅处理两个呼叫,以便完成两个订阅完成后的最终确定触发器。这是我现在这样做的方式,在第一次可观察到的触发器之后,最终确定触发器,不要等待第二个触发器。

private getTemplate(){
this.loading = true;
this.service.getTemplate()
.pipe(
  finalize(() => this.loading = false)
)
.subscribe(
  (response) => {
    if (response) {
       this.createImage(response.link);
    }
  }
)

}

public createImage(link: string) {
this.service.createImage(link)
.subscribe(
  (response) => {
    this.image = response;
  }
)

I'm new to RXJS and I have one thing that I want to achieve but I don't know how.

I Have 2 API calls. But the second one depends on the value of the first one. The problem is that I want to handle both calls with one subscribe so the finalize triggers when both subscriptions are finished. Here is how I do it now where the finalize triggers after first observable finishes and don't waits for second one.

private getTemplate(){
this.loading = true;
this.service.getTemplate()
.pipe(
  finalize(() => this.loading = false)
)
.subscribe(
  (response) => {
    if (response) {
       this.createImage(response.link);
    }
  }
)

}

public createImage(link: string) {
this.service.createImage(link)
.subscribe(
  (response) => {
    this.image = response;
  }
)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

作妖 2025-02-20 16:23:28

我将使用switchmap

private getTemplate(){
  this.loading = true
  this.a2vService.getNetworkTemplate().pipe(
    filter(response => !!response),
    switchMap(response => this.createImage(response.link)),
    finalize(() => this.loading = false)
  ).subscribe()
}

public createImage(link: string) {
  return this.service.createImage(link).pipe(
    tap(response => {
      this.image = response
    })
  )
)

switchmap将执行第二个可观察的第二个可观察到的。由于两个可观察的物品都在单个pipe()中,因此您可以将finalize()放在此处,当第二次可观察的发射时会触发。

create -Image返回可观察到的也很重要,因此可以在pipe()中使用它。

如您所见,.subscribe()在上面是空。实际上,我们可以将最终确定的内容放在这里,并且应该行为相同。

private getTemplate(){
  this.loading = true
  this.a2vService.getNetworkTemplate().pipe(
    filter(response => !!response),
    switchMap(response => this.createImage(response.link))
  ).subscribe(() => {
    this.loading = false
  })
}

如何将数据从getNetworkTemplate传递到subscribe()回调:

private getTemplate(){
  this.loading = true
  this.a2vService.getNetworkTemplate().pipe(
    filter(response => !!response),
    switchMap(response => 
      combineLatest([of(response), this.createImage(response.link)])
    )
  ).subscribe(([networkTemplateResponse, createImageResponse]) => {
    this.loading = false
  })
}

I would handle it with a switchMap

private getTemplate(){
  this.loading = true
  this.a2vService.getNetworkTemplate().pipe(
    filter(response => !!response),
    switchMap(response => this.createImage(response.link)),
    finalize(() => this.loading = false)
  ).subscribe()
}

public createImage(link: string) {
  return this.service.createImage(link).pipe(
    tap(response => {
      this.image = response
    })
  )
)

The switchMap will execute the second observable after the first one emitted. Since both Observables are in a single pipe(), you can put the finalize() here too which will trigger when the second observable emitted.

Also important to return the Observable from createImage so it can be used inside the pipe().

As you can see, the .subscribe() is empty above. We can actually put the finalize stuff here and it should behave the same.

private getTemplate(){
  this.loading = true
  this.a2vService.getNetworkTemplate().pipe(
    filter(response => !!response),
    switchMap(response => this.createImage(response.link))
  ).subscribe(() => {
    this.loading = false
  })
}

How to pass the data from getNetworkTemplate to the subscribe() callback:

private getTemplate(){
  this.loading = true
  this.a2vService.getNetworkTemplate().pipe(
    filter(response => !!response),
    switchMap(response => 
      combineLatest([of(response), this.createImage(response.link)])
    )
  ).subscribe(([networkTemplateResponse, createImageResponse]) => {
    this.loading = false
  })
}
默嘫て 2025-02-20 16:23:28

您可以根据第一个结果使用SwitchMap订阅第二个流。您可以使用过滤器来确保仅如果第一个响应通过(if(wiss)),则只能进入第二个。

您可以写下这样的东西:

private getTemplate() {

  this.loading = true;
  this.a2vService.getNetworkTemplate().pipe(

    filter(response => !!response),
    switchMap(resp => this.service.createImage(resp.link)),
    finalize(() => this.loading = false)

  ).subscribe(resp => this.image = resp);
  
}

You can use switchMap to subscribe to your second stream based on the result of the first. You can use filter to ensure you only move on to the second if the first response passes (if (response)).

You can write this something like this:

private getTemplate() {

  this.loading = true;
  this.a2vService.getNetworkTemplate().pipe(

    filter(response => !!response),
    switchMap(resp => this.service.createImage(resp.link)),
    finalize(() => this.loading = false)

  ).subscribe(resp => this.image = resp);
  
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文