处理具有数据限制的重复API查询的最佳方法

问题描述 投票:1回答:2

我正在使用eBay API,尤其是使用GetMultipleItems调用,该调用向api查询提供了商品ID列表,以返回数据。我面临的问题是,每个查询的API限制为20个项目ID。我正在节点的后端进行呼叫,并通过React和Redux返回数据。

这是我在React前端打电话给我的动作创建者的地方。

 useEffect(() => {
    props.getUpdates(formatFavs);
  }, [props.favorites]);

请注意,formatFavs是用逗号分隔的itemID的列表

这是我的getUpdates操作创建者

export const getUpdates = id => {
  return async dispatch => {
    const updates = await dataService.getMultiple(id);
    dispatch({
      type: "GET_DATA",
      data: updates
    });
  };
};

哪个指向我对后端的axios调用。

const getMultiple = query => {
  const request = axios.get(baseUrl + `?id=${query}`);
  console.log("URL", baseUrl + `?id=${query}`);
  console.log("Request", request);
  return request.then(response => response.data);
};

这是结果呼叫的样子

https://open.api.ebay.com/shopping?callname=GetMultipleItems&appid=XX&responseencoding=JSON&ItemID=231560863628,223787055529,392521444227,352879382550,274129160671,274129160671,274129160671,123998356843,223787055529,383011548243,223787055529,392521444227,352879382550,123998356843,274129160671,133268486829,223787404912'

当前,如果有20个以上的ID,则会在API端生成错误。

我需要弄清楚如何处理id超过20个的任何情况

我的最初思路是在我的getMultiple通话开始时添加条件语句。

类似

if query.length >20 {
   newQuery = query.slice(1,19) 
   const request = axios.get(baseUrl + `id=${newQuery}
   return request.then(response => response.data)
 }

尽管我不确定从这儿去哪里...只是在寻找一些建议,因为我正在努力提出正确的解决方案

已更新-根据Kostas指导完成了此工作。这是代码:

import axios from "axios";
const baseUrl = "/getMultiple";

async function getMultiple(query) {
  if (query.length < 21) {
    const request = axios.get(baseUrl + `?id=${query}`);
    return request.then(response => response.data);
  }

  let ids = [...query];
  console.log("IDS", ids);
  const batchSize = 20;
  const requests = [];

  while (ids.length) {
    let currentBatch = ids.splice(0, batchSize);
    console.log("Current batch", currentBatch);
    requests.push(axios.get(baseUrl + `?id=${currentBatch}`));
  }

  console.log("Requests", requests);

  const final = await Promise.all(requests);
  const finalData = final.map(dataArray => dataArray.data);
  const arrayData = Array.prototype.concat(...finalData);

  return arrayData;
}

export default {
  getMultiple
};
javascript node.js reactjs axios
2个回答
0
投票

您可以将请求分为多个批次,并使用Promise.all()来按以下方式获取结果:

async function getMultiple( input ) {

    if ( input.length < 21 ){
        return axios.get( baseUrl + `id=${input}` );
    } 

    let ids = [ ...input ];
    const batchSize = 20;  
    const requests = [];

    while ( ids.length ){

        let currentBatch = ids.splice( 0, batchSize );
        requests.push( axios.get( baseUrl + `id=${currentBatch}` ) );    

    }

    return await Promise.all( requests );

}
let input = [ 1, 2, 3, 4, ... 24, 25, 25 ];

getMultiple( input ).then( res => console.log(res) );

1
投票

我会打断您的电话,并将它们分组为Promise数组。 axios.get返回一个Promise,因此您可以使用它代替示例函数(httpGet(id)

基本上,创建一种方法来接收n个收藏夹。然后,通过axios调用将您的ID分成20组。因此,如果您收到60个ID,则最终将获得3个api调用(每个API调用具有20个ID)。

然后,您可以在Promise.all的返回中获取整个结果列表,并从那里连接数组(如果需要)。在下面,我不是将您的ID按20分组,而是演示了如何利用Promise.all发送一堆消息并等待所有消息解析并对该结果执行某些操作。

function httpGet(id) {
  return fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
    .then(response => response.json());
}

function getFavorites(ids) {
  // TODO: Implement logic to group promise array by chunks of 20
  const promises = ids.map(id => httpGet(id));
  return Promise.all(promises);

}

getFavorites([1, 2, 3, 4, 5, 6, 7, 8, 9]).then(results => console.log(results));
© www.soinside.com 2019 - 2024. All rights reserved.