首页 > 解决方案 > 如果响应包含 50 个 id,如何使用递归进行连续的 axios 调用?

问题描述

我有一个函数可以循环遍历带有页码的 URL 数组,并且我希望响应最多包含 50 个 id。我想返回 id 或增加页面计数器,直到响应返回少于 50 个 id。下面保存的代码是两个独立的部分,请求功能是无法正常工作的部分。

我正在使用 axios 调用服务器,但出现错误:“UnhandledPromiseRejectionWarning”

let urlArr = [
      'https://restapi.com/token=TOKEN_ACCESS&usr=Fred&page=', 
      'https://restapi.com/token=TOKEN_ACCESS&usr=Skip&page='
];
let users = [];
let promises = [];
let pageCounter;
for (var i = 0; i < urlArr.length; i++) {
   pageCounter = 0;
   promises.push(
         users.push(this.Request(urlArr[i], pageCounter))
    )
}
Promise.all(promises).then(() => console.log(users));

Request:(url, pageCounter)=>{
      return axios.get(url+pageCounter).then(response => {
            let itemCounter = 0;
            let arr = [];    //Not sure if this array is needed
            response.data.forEach((item)=>{
                itemCounter++;
                arr.push(item.id);
                if(itemCounter == 50){ //If counter equals 50 go to next page
                    pageCounter++;
                    return Request(url, pageCounter)
                }
                return arr;  //return an array with ids
            });            
        });    
}

我希望输出是一个充满 id 的数组 ex: [1, 2, 3]

标签: javascriptasynchronouspromise

解决方案


不断询问存在多少记录是一个常见的请求,因为这使得很难知道服务何时根本不提供页面信息,例如

{
    "page": 2,
    "per_page": 3,
    "total": 12,
    "total_pages": 4
}

对于这个特定问题,您只有一个解决方案:继续向服务询问记录,直到它不再给您...

所以现在的问题是如何获得重复数据,流程可能类似于:

  1. 每页请求数据
  2. 对于每个响应,检查返回的数据是否“完整”
  3. 如果没有,请附加页面计数器并转到 1

在 Javascript 中,使用 Axios 和 ES6,您可以轻松地立即执行此操作,async/await因为您需要等到处理请求才能检查响应,例如,使用Regres.in Fake API您最终会得到

const Axios = require('axios');

const API = 'https://reqres.in/api';
const MAX_PAGE = 3;
const COUNTER_START = 1; // for this fake api, paging starts with 1

const getAll = async () => {
    let pageCounter = COUNTER_START;
    let isProcessing = true;

    while (isProcessing) {
        const json = await getPagedData(pageCounter); // get data
        isProcessing = !isFinished(json.data); // check data
        pageCounter += 1; // increase page counter
    }
}

const isFinished = data => data.length !== MAX_PAGE;

const getPagedData = page => Axios.get(`${API}/users?page=${page}`).then(res => {
    //console.log(`### [ PAGE ${page} ] ###\n${JSON.stringify(res.data, null, 4)}`);
    console.log(`### [ PAGE ${page} ] ### -> returned ${res.data.data.length} objects`);
    return res.data;
});

getAll();

你会有类似的东西

node .\index.js
### [ PAGE 1 ] ### -> returned 3 objects
### [ PAGE 2 ] ### -> returned 3 objects
### [ PAGE 3 ] ### -> returned 3 objects
### [ PAGE 4 ] ### -> returned 3 objects
### [ PAGE 5 ] ### -> returned 0 objects

推荐阅读