У меня есть файл запроса axios, который идет и получает много запросов, которые я использовал асинхронную функцию для всего этого, чтобы я мог задерживать запросы в секунду, отправленные на api (их предел скорости).
Мой код:
import axios from 'axios';
export const litecoinApi = async (addresses, resolve, reject) => {
let addressesBalance = {};
let addressRequests = [];
addresses.forEach(address => {
addressRequests.push("https://api.blockchair.com/litecoin/dashboards/address/" + address);
});
function delay() {
return new Promise(resolve => {
setTimeout(() => resolve(), 2000);
});
}
let i;
for (i = 0; i < addressRequests.length; i++) {
await axios.get(addressRequests[i])
.then((res) => {
console.info(res.data.data);
const data = res.data.data[addresses[i]];
console.info('data', data.address.balance);
addressesBalance[addresses[i]] = data.address.balance / 100000000;
}).catch((error) => {
console.info(error);
});
await delay();
}
resolve(addressesBalance);
// let i;
// for (i = 0; i < addressRequests.length; i++) {
// await axios.get(addressRequests[i])
// .then((res) => {
// const data = res.data.data;
// console.info(data);
// addressesBalance[data.address.toString()] = data.confirmed_balance.toString();
// }).catch((err) => {
// console.info(err.response);
// });
// await delay();
// }
// resolve(addressesBalance);
};
Я просто обращаюсь к запросу и просматриваю объект, чтобы получить (баланс адреса).
Я получаю предупреждение в консоли:
./src/apis/litecoin.js
Line 20: Don't make functions within a loop no-loop-func
Проблема, с которой я столкнулся, - это строка 20:
.then((res) => {
На самом деле проблема не в этом, это явно строка 22:
const data = res.data.data[addresses[i]];
адреса - это просто массив строк. Когда я удаляю доступ к ключевым адресам [i] из объекта res.data.data, предупреждение исчезает. Объект res.data.data в консоли:
{LWcXUB6ny88tK49TK1V6KprE5oDcJ1zJhx: {…}}
LWcXUB6ny88tK49TK1V6KprE5oDcJ1zJhx:
address:
{type: null, script_hex: "", balance: 0, balance_usd: 0, received: 0, …}
transactions:
[]
Таким образом, адрес litecoin LWcXUB6ny88tK49TK1V6KprE5oDcJ1zJhx - это ключ в объекте, а значение - это другой объект с адресом и транзакциями в качестве ключей. Моя конечная цель - сбалансировать значение адресного ключа.
Я оставил комментарий для цикла ниже (который был для немного другого api), потому что я не получаю предупреждения в нем. Проблема в том, что просто нет способа получить доступ к значению адресного ключа litecoin без того, как вы обычно получаете доступ к ключу в объекте.
Я изменил эту строку:
const data = res.data.data[addresses[i]];
К:
const data = res.data.data;
const address = Object.keys(data);
Как только я пытаюсь использовать Object.keys, я получаю сообщение об ошибке, не говоря уже о доступе к первому ключу:
address[0]
Это оставляет меня в полной растерянности, потому что тогда я буквально не могу получить доступ к объекту, не получив сообщение об ошибке, что я использую цикл в функции.
Разрешение и отклонение исходят из обещания, что эта функция будет вызвана, и я использую функцию async, чтобы дождаться, пока все запросы api не будут выполнены, прежде чем я разрешаю обещание, что эта функция находится в.
Затем это обещание уходит и правильно устанавливает мое состояние.
У кого-нибудь есть идеи? Я смотрел на многие другие SO, но, похоже, никто не занимается проблемой, с которой я здесь. Честно говоря, я вообще не понимаю, как я использую функцию в цикле.
Я не знаю, как получить доступ к ключу в объекте.
В:
.then((res) => {
...
}
Просто ждет обещания axios.get. Этот цикл get / then работал в других запросах api без этой проблемы. Кроме того, предупреждение действительно возникает только при попытке передать ключ объекту внутри цикла for.
Я должен сообщить вам, что все работает правильно, с предупреждением. Меня просто бесит, что я не могу избавиться от этого предупреждения.
Большое спасибо за ваше время и понимание.
Если я объявлю свою асинхронную функцию вне цикла for, я не могу использовать await в цикле for, тогда могу ли я? Или вы говорите, что поместите запрос axios в функцию вне цикла, а затем вызовите ее?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


По совету Теему (если вы хотите повторно опубликовать этот ответ, я дам вам ответ).
Я пробовал это:
import axios from 'axios';
export const litecoinApi = async (addresses, resolve, reject) => {
let addressesBalance = {};
let addressRequests = [];
addresses.forEach(address => {
addressRequests.push("https://api.blockchair.com/litecoin/dashboards/address/" + address);
});
function delay() {
return new Promise(resolve => {
setTimeout(() => resolve(), 2000);
});
}
function axiosRequest(addressRequests, addresses) {
axios.get(addressRequests)
.then((res) => {
console.info(res.data.data);
const data = res.data.data[addresses];
console.info('data', data.address.balance);
addressesBalance[addresses] = data.address.balance / 100000000;
}).catch((error) => {
console.info(error);
});
}
let i;
for (i = 0; i < addressRequests.length; i++) {
await axiosRequest(addressRequests[i], addresses[i]);
await delay();
}
resolve(addressesBalance);
};
Это просто перемещает запрос axios в свою собственную функцию, которая затем передает запросы и адреса.
Ожидание не может работать в функции axiosRequest (), но вы все равно можете использовать его в цикле for для решения проблемы.
Это решило мою проблему, большое спасибо Теему!
Вы можете попробовать что-то простое и простое за один раз:
import axios from 'axios';
export const litecoinApi = async (addresses) => {
const balance = {};
for (const address of addresses) {
const currentAddress = `https://api.blockchair.com/litecoin/dashboards/address/${address}`;
const result = await axios.get(currentAddress)
const data = result.data.data[address];
console.info(data);
balance[address] = data.address.balance / 100000000;
}
return balance;
}
Или вы можете обрабатывать все запросы параллельно:
const result = await Promise.all(promises);
О, хороший момент, хотя и с функцией обещания await delay (), чтобы я мог оставаться ниже лимита запроса. Без задержки это могло бы происходить быстрее, чем API может позволить мне делать запросы, в зависимости от того, насколько быстро будет ответ. Спасибо за ответ!
Объявите функцию вне цикла и поместите ссылку на аргумент
then. В качестве альтернативы отключите функция без цикла в конфигурации линтера.