【问题标题】:Multiple api calls in loop fails循环中的多个 api 调用失败
【发布时间】:2020-07-09 01:30:07
【问题描述】:

在调用外部 api 以在我的 node/express 后端的循环中获取信息时遇到一些问题。我需要从循环中获取的信息,以便从端点获取正确的数据。当我遍历数据并进行调用时,我得到了这个错误。

{ message: 'Too Many Requests Limit 30. Reset time 1594218437315',
  status: 429 }

我有时会返回正确的数据,有时只会返回此消息。我需要打大约 10 000 个电话。我已经在 SO 上尝试了多个限制库和很多代码,但它几乎总是相同的结果,即错误消息或根本不起作用。

我想我需要一种方法一次发送大约 20-30 个请求,然后等待一秒钟左右,然后继续。或者还有其他更好的方法吗?我将如何实现这一目标?

 const product = await NewProduct.find({});
  product.map((item, index) => {
    item.stores.map(async inner => {
      inner.trackingUrl = await fetchRetry(inner.programId, inner.productUrl)
    })
  })


async function fetchRetry(id, urlToTrack) {

  url1 = 'https://api.adtraction.com/v2/affiliate/tracking/link/?token=token';
  const data = {
    channelId,
    programId: id,
    shortLink: true,
    url: urlToTrack
  };

  const options = {
    method: 'POST',
    headers: {
      'Content-type': 'application/json',
      Accept: 'application/json',
      'Accept-Charset': 'utf-8',
    },
    body: JSON.stringify(data),
  };

  const res = await fetch(url, {
    method: 'POST',
    headers: {
      'Content-type': 'application/json',
      Accept: 'application/json',
      'Accept-Charset': 'utf-8',
    },
    body: JSON.stringify(data),
  });
  const json = await res.json();
  console.log(json) // Error
  return json.trackingUrl;

}

【问题讨论】:

  • 如果他们设置了限制,那么很难不设置一个计时器来遵守他们的限制,或者如果他们没有办法发送“批量”请求,请与他们核实(这有时是可能的)
  • 您是否从服务器收到此错误?
  • @jinwar 是的,完全正确。那是我的问题,真的不知道该怎么做。
  • @Ibrahim 没错,我在响应中得到了错误。

标签: node.js express async-await


【解决方案1】:

好吧,我将与您分享我在一个项目中所做的一些事情。对于您使用 api 调用的所有数据。继续发出请求,当您遇到任何错误或限制响应时,请等待 5 分钟(或在您的 api 中要求)并移至上一个索引(用于调用 api 的上一个数据)

async function callAPI(data) {
    for (let index = 0; index < data.length; index++) {
        try {
            // api call with your data 
            yourApiCall(data[index]);
        } catch (e) {
            if (e.type == "RequestThrottled") {
                let oneMinute = 60000;
                // wait for the time your request will be availabl
                await sleep(5 * oneMinute);
                // because of error in this request get back to 
                //previous request (or data)
                index--;
            }
        }
    }
}

函数使用 setTimeout 同步等待。

async function sleep(ms) {
    await new Promise((resolve) => setTimeout(resolve, ms));
}

此外,您可能希望在某个后台进程上运行它,因为它可能会阻塞您的主事件循环。

【讨论】:

  • 好的,谢谢。您将如何将您的代码与我的代码一起使用?就我而言,data 是什么?我看不出data 相当于什么。
  • 好吧,就您而言,ProgramId 和 productUrl 似乎是您将调用 api 的数据
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多