如何基于第一个响应在RxJS中发出多个Ajax请求

时间:2018-08-06 17:27:38

标签: rxjs redux-observable

我正在使用Redux可观察的史诗来使用搜索端点从GitHub上的特定组织获取回购协议。我的主要问题是我需要按“观察者”排序,因此我需要所有存储库,但是GitHub只允许一个返回每页最多100个。响应包括“ total_count”,我可以使用它来计算我还需要发出多少个请求(页面数)。到目前为止,这是我的代码:

export const fetchRepos = actions$ =>
  actions$.pipe(
    ofType(FETCH_REPOS),
    switchMap(action =>
      ajax.getJSON(`https://api.github.com/search/repositories?q=org:${action.payload.orgName}&per_page=100`).pipe(
        flatMap((response) => ([setRepos(response.items), setCurrentOrg(action.payload.orgName), fetchReposSuccess(response.item)])),
        catchError(error => of(fetchReposFailed()))
      )   
    )   
  ); 

我想知道如何使用第一个响应的“ total_count”道具基于该数字发出更多的ajax请求,并合并到一个流中而又不会过多更改我的代码。

1 个答案:

答案 0 :(得分:2)

我认为最简单的方法是使用expand()运算符,该运算符递归地投影来自Ajax调用的响应,您可以在其中确定是否需要抓取更多页面。因此,您甚至不需要使用total_count,因为您可以简单地继续下载页面,直到获得的项目少于per_page参数为止。

例如,这是我如何从帐户中获取所有存储库的方法:

const PER_PAGE = 10;
const API_URL = 'https://api.github.com/search/repositories';

const makeAjax = page => ajax.getJSON(`${API_URL}?q=org:martinsik&per_page=${PER_PAGE}&page=${page}`).pipe(
  map(response => ([page, response])),
);

makeAjax(1)
  .pipe(
    expand(([page, response]) => response.items.length < PER_PAGE
      ? empty()
      : makeAjax(page + 1)
    ),
    map(([page, response]) => response),
    toArray(),
  )
  .subscribe(console.log);

观看现场演示:https://stackblitz.com/edit/rxjs6-demo-kccdwz?file=index.ts