Управление вызовами Axios в цикле в узле

#node.js #axios

#node.js #аксиос

Вопрос:

мой код выходит из-под контроля.

У меня есть скрипт, который считывает файл json и повторяет его, используя ключ «Id» в качестве значения api в вызове axios get. Данные из ответа сохраняются в каталоге.

Я бы хотел, чтобы одно значение было считано из исходного файла, был сделан этот вызов, данные были сохранены, а затем была проведена следующая итерация. Я бы хотел, чтобы это произошло в приятной, скучной синхронной манере.

Что на самом деле происходит, так это то, что все итерации выполняются немедленно, переполняя сервер, вызывая 400 ошибок «слишком много запросов».

Я пытался использовать setInterval в разных точках кода.

Я также пытался использовать axios-расширения для ограничения запросов.

Я попытался использовать блок, чтобы проверить, запущен ли цикл, и если да, то не запускать его снова.

Я даже вставил функцию, чтобы проверить, существует ли файл данных, и попытаться вытащить его, только если это не так. Похоже, он также игнорирует это.

Ничто из того, что я пробовал, не оказало никакого влияния.

Я предполагаю, что 400-е вызывают повторные попытки невыполненных обещаний и что я просто не справляюсь с ними должным образом.

Чего я не понимаю, так это почему я не могу заставить запросы замедляться.

Я знаю, что это, наверное, что-то глупое, но я уже несколько дней бьюсь головой об стену, пытаясь заставить это работать.

Любая помощь будет признательна.

 function getAPI(activeURL, callId) {    let idPath = (detailDataPath   activeURL)   //This if seems to be ignored. It makes the call even if the file exists.    if (fs.existsSync(idPath)) {  // path exists  console.log(activeURL, "saved");  } else {   //I've tried to wrap the get in a setInterval   instance.get(activeURL, () =gt; {   })  .then(resp =gt; {  apiData = (resp.data);    try {  (async () =gt; {  saveDetail(apiData);  })();    } catch (error) {  console.log(resp.status);  }  })  .catch(error =gt; {  console.log("error", callId);  })  } }  function loupe(activeURL, callId) {   //I've set this value to various values. If calls are made more than 500ms apart, I will get 400 errors   setInterval(function (){  getAPI(activeURL, callId);  }, 1000); }  function mainLoop(sourceData) {   fs.readFile(sourceData, "utf8", (err, data) =gt; {  if (err) {  console.error(err);  }  let detailList = JSON.parse(data);   //I've tried forEach here   for (let i = 0; i lt; detailList.length; i  ) {   let activeURL = (detailList[i].Id);  callId = i;   //I've tried wrapping this in a setInterval  loupe(activeURL, callId);    }   }) } function throttle() {  hasRun = true;  mainLoop(sourceData) }  let hasRun = false;  function runOnce() {  if (!hasRun) throttle();  console.log("run complete") } runOnce();  

Ответ №1:

После попытки Bluebird и p-Limit я смог получить вызовы api с узким местом.

Это далеко не идеально, но работает стабильно, без 400 ошибок.