【问题标题】:Observable make request multiple times and collect response togetherObservable 多次发出请求并一起收集响应
【发布时间】:2021-03-02 19:26:41
【问题描述】:

在数据库中我有 19 个用户。 在我的 API 中,一次调用只能得到 5 个结果。

如果我想获得所有这些,我需要请求 4 次,每次获得 5 个用户。通过start 查询,我将更改我希望新用户从哪个位置获得。

我正在尝试在 RxJS 中与 redux-observable 一起使用。 我有一些想法,但也许我的方法是必要的,而 RxJS 是相反的意识形态。

      // get users from API and `pipe` them helps me to see actual data and to count length of array
     function getUsers(position = 0) {
        return ajax.getJSON(`${API}/users?_start=${position}&_limit=5`).
            pipe(map(({data}) => ({responseLength: data.length, data})))
    }

// here when I got response if array.lenght is equal to 5, I know that I need to do fetch of data again.
// Problem is encountered here: if I do recursion after doing I will get only last result, not both of them, 
// if I put my previous result into array, and then recursion result again push in array it become too complicated after 
// in userFetchEpic to manipulate with this data
    function count(data) {
        return data.pipe(
            map(item => {
                if (item.responseLength === 5) {
                    count(getUsers(5));
                }
                return {type: "TEST" , item}
            })
        )
    }

    function userFetchEpic(action$) {
        return action$
            .pipe(
                ofType(USER_FETCH),
                mergeMap(() => {
                    return count(getUsers()).pipe(
                        map(i => i)
                    )
                })
            );
    }

我的代码在这里只是为了展示我的想法。

主要问题是递归如何将所有值保存在一起,如果我将值保存在数组中。 然后我需要遍历一系列可观察对象,这在我的脑海中听起来很复杂。 :)

可能这个问题有更简单更好的解决方案。

【问题讨论】:

  • 你可以使用scan !?

标签: rxjs observable redux-observable


【解决方案1】:

19 个用户,4 个并发呼叫

我重新安排了您的 get-users 函数以生成 4 个 Ajax 调用,同时运行它们,然后将结果扁平化为一个数组。这应该让您在一个数组中获得所有 19 个用户。

function getUsers() {
  return forkJoin(
    [0,5,10,15].map(position => 
      ajax.getJSON(`${API}/users?_start=${position}&_limit=5`)
    )
  ).pipe(
    map(resArray => resArray.flatMap(res => res.data))
  )
}

function userFetchEpic(action$) {
  return action$.pipe(
    ofType(USER_FETCH),
    mergeMap(_ => getUsers())
  );
}

泛化:递归获取用户

同样,这将返回所有 19 个用户,但这次您不需要提前知道您有 19 个用户。另一方面,这会按顺序进行所有调用,所以我预计它会更慢。

您会注意到这是递归完成的。您正在以这种方式创建调用堆栈,但只要您没有数百万用户,这应该不是问题。

function getUsers(position = 0) {
  return ajax.getJSON(`${API}/users?_start=${position}&_limit=5`).pipe(
    switchMap(({data}) => 
      data.length < 5 ?
      of(data) :
      getUsers(position + 5).pipe(
        map(recursiveData => data.concat(recursiveData))
      )
    })
  );
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多