【问题标题】:Multiple HTTP Requests with RxJS, with parameters使用 RxJS 的多个 HTTP 请求,带参数
【发布时间】:2018-07-17 10:54:14
【问题描述】:

我称之为 api

https://jokerleb.com/wp-json/wp/v2/ads/

我抓取每个广告的id,然后将其附加到此网址

https://jokerleb.com/wp-json/wp/v2/media?parent=24385

我的代码是

  loadAds() {
    let i = 0;
    this.HttpClient.get(ENV.site_url + ENV.ads_url)
      .subscribe(res => {
        this.ads = this.ads.concat(res);

        this.HttpClient.get(ENV.site_url + ENV.ads_thumb_url + this.ads[i].id + "&&ads/" + this.ads[i].id)
          .subscribe(res => {
            this.items = this.items.concat(res);
            console.log(ENV.site_url + ENV.ads_thumb_url + this.ads[i].id + "&&ads/" + this.ads[i].id);
            i++;
          })
      }
      )
  }

代码有效,但是:

  • 我最终得到了两个不同的数组,我无法将它们正确合并到一个数组中items
  • 我讨厌我必须做两个单独的订阅,它有效但感觉不对

基本上我想得到一个包含来自两个端点的所有项目的数组。

所以对象id=24385应该返回一个数组

https://jokerleb.com/wp-json/wp/v2/ads/24385

https://jokerleb.com/wp-json/wp/v2/media?parent=24385

【问题讨论】:

  • 从我在这里看到的......你得到一个 id 数组,你想用每个 id 调用另一个 url?
  • @SurajRao 是,然后将第一个请求的结果与第二个请求的结果合并,这样我就可以遍历视图中的 1 个数组

标签: angular ionic-framework rxjs ionic3


【解决方案1】:

您需要做的是使用concatMap 合并两个列表。 例如:

getService1(id1).pipe(
   // take array1 and return [array1, array2]
   concatMap( array1=> return zip(of(array1), getService2(array1[information])))
   // concat Array1 and array2 
   map( [array1, array2] =>  array1.concat(array2))
)
.subscribe( combinedArray => ...)

如果您的服务每个发出 1 个项目,您可以将 concatMap 替换为 switchMapmergeMapexhaustMap;在这种情况下,它们的行为都相同。此外,您还可以将zip 替换为forkJoin。相反,如果您的服务发出超过 1 个值,您将不得不根据您的需要选择一个行为。

【讨论】:

  • 在考虑 switchMap 和 forkJoin... 有什么理由 zip 更好?
  • Forkjoin 不起作用,您需要在调用第二个服务之前获得第一个服务的结果。如果您的服务发出一个值,switchMap、concatMap、exhaustMap、mergeMap 工作并且是等效的。
  • 来自 switchMap 的 第二次调用 将是 forkJoin
  • 是的 forkJoin (of (array1), service2) 看起来没问题
【解决方案2】:

您可以 switchMap 到第二个调用 forkJoin (发送所有调用并等待最终响应数组)

this.HttpClient.get(ENV.site_url + ENV.ads_url).pipe(
  switchMap(res => {
    this.ads = this.ads.concat(res);
    let obs  = this.ads.map(ad => this.HttpClient.get(ENV.site_url + ENV.ads_thumb_url + ad.id + "&&ads/" + ad.id);//create an observable array
      return forkJoin(...obs).pipe(map(res=>res.concat(this.ads)));//map the response with initial array and return concatenated array.
  })
  ).subscribe(finalArray =>{
})

【讨论】:

  • 问题是this.HttpClient.get(ENV.site_url + ENV.ads_thumb_url + ad.id + "&&ads/" + ad.id)); 将只返回图像,你可以在这里检查https://jokerleb.com/wp-json/wp/v2/media?parent=24408&&ads/24408 这就是我试图做的,但不能在网址中结合两者。如您所见,您获得的数组仅显示缩略图,没有关于广告标题、城市、电话等信息
  • 我昨天尝试做类似的事情并卡住了wordpress.stackexchange.com/questions/308750/…
  • 看来您可能需要检查您将从中获取所需数据的 api。
【解决方案3】:

感谢所有回答的人,我会随机选择一个接受的答案,因为它们非常好,不过我是这样解决的。

提供者:

  getAds(): Observable<any[]> {
    return this.http.get(ENV.site_url + ENV.ads_url)
      .flatMap((ads: any[]) => {
        if (ads.length > 0) {
          return Observable.forkJoin(
            ads.map((ad: any) => {
              return this.http.get(ENV.site_url + ENV.ads_thumb_url + ad.id)
                .map((res: any) => {
                  let media: any = res;
                  ad.media = media;
                  return ad;
                });
            })
          );
        }
        return Observable.of([]);
      });
  }

供应商是

首页.ts

 ngOnInit() {
    this.adsProvider.getAds().subscribe((data: any) => {
      this.items = data;
    });
  }

感谢this article: Combining Observables in series and in parallel

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    • 2021-05-26
    • 1970-01-01
    • 2019-02-08
    相关资源
    最近更新 更多