【问题标题】:Axios recursion for paginating an api with a cursor使用光标对 api 进行分页的 axios 递归
【发布时间】:2019-01-01 18:56:13
【问题描述】:

如何使用 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"
    }
}

提前感谢您的帮助。

【问题讨论】:

    标签: javascript node.js recursion axios


    【解决方案1】:

    这是一个从响应中管理光标的递归函数:

    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))

    【讨论】:

    • 谢谢你。这似乎可以通过一些修改来工作,主要是围绕axios 的工作方式和 API 的形状。 data.push(...response.data.data)return getUsers(response.data.pagination.cursor, data)
    • 酷@TechnoTim 很高兴至少指出了正确的方向。
    【解决方案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);
      })
    

    【讨论】:

    • 谢谢你。我将接受马克的回答,因为它包含了光标的逻辑。感谢您的帮助!
    猜你喜欢
    • 2021-06-02
    • 1970-01-01
    • 2022-10-09
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 2015-04-19
    • 2021-05-24
    相关资源
    最近更新 更多