Не выполнять функции внутри цикла no-loop-func Axios Request async await

У меня есть файл запроса 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.

Я должен сообщить вам, что все работает правильно, с предупреждением. Меня просто бесит, что я не могу избавиться от этого предупреждения.

Большое спасибо за ваше время и понимание.

Объявите функцию вне цикла и поместите ссылку на аргумент then. В качестве альтернативы отключите функция без цикла в конфигурации линтера.

Teemu 28.11.2018 20:29

Если я объявлю свою асинхронную функцию вне цикла for, я не могу использовать await в цикле for, тогда могу ли я? Или вы говорите, что поместите запрос axios в функцию вне цикла, а затем вызовите ее?

ekr990011 28.11.2018 20:36
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
236
2

Ответы 2

По совету Теему (если вы хотите повторно опубликовать этот ответ, я дам вам ответ).

Я пробовал это:

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 может позволить мне делать запросы, в зависимости от того, насколько быстро будет ответ. Спасибо за ответ!

ekr990011 28.11.2018 21:06

Другие вопросы по теме