#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 ошибок.