Axios递归用于使用光标分页API

15

如何使用axios和游标分页API?我希望能够递归调用此函数,直到response.data.length <1 ,并在完成后返回包含所有集合中所有项的整个数组。另外需要注意的是,我需要将游标传递给后续的调用。

function getUsers () {
    return axios.get('/users') // API supports a cursor param (?after=)
             .then(response => {
               // returns an array with a cursor
               // see response below
               console.log(response.data)
             })
}

示例响应:

{
    "total": 100,
    "data": [
        {
            user: "Bob"
        },
        {
            user: "Sue"
        },
        {
            user: "Mary"
        },
    ],
    "pagination": {
        "cursor": "lkdjsfkljsdkljfklsdjfkjsdk"
    }
}

非常感谢您的帮助。

2个回答

22

这里是一个递归函数,用于管理响应中的光标:

function getUsers (cursor, data = []) {
    return axios.get('/users' + (cursor ? '?after='+cursor : '')) // API supports a cursor param (?after=)
      .then(response => {
          if (response.data.length < 1 ) return data
          data.push(...response.data)
          return getUsers(response.pagination.cursor, data)
      })
}
// use it to get data
getUsers()
.then(data => console.log("final data", data))

这是使用一个伪造的 axios 函数和一些额外的日志记录来展示其顺序的工作方式:

// Fake axios get -- just return numbers so it's easy to test
let axios = {
    data: data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
    get(url) {
        let cursor = parseInt(url.split('?after=')[1] || 0)
        console.log("cursor:", cursor)
        let ret_data = data.slice(cursor, cursor +5)
        return new Promise(resolve => setTimeout(() => resolve({
            "total": 15,
            "data": ret_data,
            "pagination": {
                "cursor": cursor +5
            }
            }), 400)
        )
    }
}

function getUsers (cursor, data = []) {
    return axios.get('/users' + (cursor ? '?after='+cursor : '')) // API supports a cursor param (?after=)
             .then(response => {
               console.log("getting data", response.data)
               if (response.data.length < 1 ) return data
               data.push(...response.data)
               return getUsers(response.pagination.cursor, data)
             })
}
getUsers()
.then(data => console.log("final data", data))


2
谢谢您的回复。经过一些修改,它看起来能够正常工作,主要涉及axios工作方式和API的形式。data.push(...response.data.data) return getUsers(response.data.pagination.cursor, data) - TechnoTim
1
很酷的@TechnoTim,很高兴至少指出了正确的方向。 - Mark
@TechnoTim 这个修改是必要的,因为如果API只返回一页,函数将返回空数据。因此,在处理分页之前,它必须先推入数组。谢谢。 - Marcio J

2

需要一个单独的递归函数,它接受一个数组,获取 /users,然后将结果推送到数组中并再次调用自身,或者如果没有更多用户,则返回结果:

function getUsers () {
  getOne()
    .then((users) => {
      // got all users
    });
}

const getOne = (users = []) => axios.get('/users')
  .then(({ data }) => {
    // Resolve the promise initialized in `getUsers` with the final array:
    if (data.length < 1) return users;
    // Else, push to the array and chain another promise onto the end:
    users.push(...data);
    return getOne(users);
  })

谢谢你。我将接受Mark的答案,因为它包括光标的逻辑。感谢你的帮助! - TechnoTim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接