【问题标题】:How to write Angular 2+ function using Observables for a Paginated api如何使用 Observables 为分页 API 编写 Angular 2+ 函数
【发布时间】:2018-01-19 07:53:39
【问题描述】:

我正在使用 instagram api。 api提供如下响应:

{
    "pagination": {
        "next_max_id": "blah",
        "next_url": "api call url here"
    },
    "data": [{ "xyz" : "data i am interested in" }]
}

我正在使用它来获得可观察的结果:this.http.get(url).map(...)

我用subscribe 编写了自己的代码,它几乎导致了无限循环。我无法从分页的“next_url”中收集后续 api 调用的所有数据。

我阅读了有关使用 concatMapflatMap 的信息,但需要更详细的解释和代码才能有效地执行此操作。

假设函数如下:

getApiResult(access_token) {
    resulltObservable = this.http.get(url).map(res => res.json());
       /* 
        logic to also get results from pagination 
        and aggregate all the results 
        */
    return finalResult;
}

注意:在某一时刻 pagination : {} 不会有 'next_url' 属性。我想停在那里。

【问题讨论】:

  • 你想继续执行直到没有next_url
  • 是的,在某一时刻pagination : {} 不会有任何财产。我想停在那里。

标签: javascript angular ionic-framework rxjs observable


【解决方案1】:

我认为这方面的东西应该可行。但不确定这是否是最佳选择。

getResultsRecursive(url) {
    return this.http.get(url)
        .flatMap(res => {
            const parsedRes = res.json();
            if(parsedRes.pagination.next_url) {
                return this.getPageResults(parsedRes.pagination.next_url)
                    .startWith(res);
            }
            return Rx.Observable.of(res)
        });
}

getApiResult(access_token) {
    const firstPage = [...];
    return this.getResultsRecursive(firstPage)
        .map(res => res.json())
        // Here we will have 1 res per each page. We could combine them into a single one (optional)
        .reduce(res => {however you want to combine the results}, []);
}

【讨论】:

    【解决方案2】:

    认为这是一个很常见的模式,所以我挖掘了一下并提出了以下递归 Rxjs ajax 处理的解决方案

    // try to mock the api
    let loadData = (url) =>
      Rx.Observable.of({
        "pagination": {
          "next_url": url
        },
        "data": [{
          "xyz": "data i am interested in"
        }]
      }).delay(2000)
    
    
    loadData('www.xyz.com').expand((obj) => {
        url = obj.pagination.next_url
        if (url)
          return loadData(url)
        return Observable.empty()
      })
      .take(3)
      .reduce((acc, curr) => {
        console.warn(curr)
        return acc.concat(curr.data)
      }, [])
      .subscribe(console.log)

    http://jsbin.com/xemowavove/edit?html,js,output

    【讨论】:

      猜你喜欢
      • 2017-11-06
      • 1970-01-01
      • 2018-06-11
      • 1970-01-01
      • 2016-08-30
      • 1970-01-01
      • 2020-04-08
      • 2017-09-09
      • 1970-01-01
      相关资源
      最近更新 更多