Не выполняйте функции в цикле no-loop-func Axios Запрос асинхронного ожидания - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть файл запросов axios, который отправляет и получает много запросов, которые я использовал для всего этого с помощью асинхронной функции, чтобы я мог задерживать запросы в секунду, отправляемые в API (их ограничение скорости).

Myкод:

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.log(res.data.data);
      const data = res.data.data[addresses[i]];
      console.log('data', data.address.balance);
      addressesBalance[addresses[i]] = data.address.balance / 100000000;
    }).catch((error) => {
      console.log(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.log(data);
  //     addressesBalance[data.address.toString()] = data.confirmed_balance.toString();
  //   }).catch((err) => {
  //     console.log(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]];

address - это просто массив строк.Когда я удаляю доступ к ключевым адресам [i] из объекта res.data.data, предупреждение исчезает.Объект res.data.data в консоли:

{LWcXUB6ny88tK49TK1V6KprE5oDcJ1zJhx: {…}}
   LWcXUB6ny88tK49TK1V6KprE5oDcJ1zJhx:
      address:
         {type: null, script_hex: "", balance: 0, balance_usd: 0, received: 0, …}
      transactions:
         []

Таким образом, адрес litecoin LWcXUB6ny88tK49TK1V6KprE5oDcJ1zJhx является ключом в объекте, а значение является другим объектом с адресом и транзакциями в качестве ключей.Моей конечной целью является баланс в значении адресной клавиши.

Я оставил закомментированный цикл for ниже (который был для немного другого API), потому что я не получаю предупреждение в этом.Проблема в том, что просто нет способа получить доступ к значению ключа адреса litecoin без того, как вы обычно получаете доступ к ключу в объекте.

Я изменил эту строку:

const data = res.data.data[addresses[i]];

To:

const data = res.data.data;
const address = Object.keys(data);

Как только я пытаюсь использовать Object.keys, я получаю ошибку, не говоря уже о фактическом доступе к первому ключу:

address[0]

Это оставляет меня в полной потере, потому что тогда ябуквально не может получить доступ к объекту, не получив сообщение об ошибке, что я использую цикл в функции.

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

Затем это обещание сбрасывается и правильно устанавливает мое состояние.

У кого-нибудь есть идеи?Я смотрел на многие другие SO, но, похоже, никто не имеет дело с проблемой, я здесь.Честно говоря, я вообще не вижу, как я использую функцию в цикле.

Доступ к ключу в объекте определенно не является функцией, которую я знаю.

The:

.then((res) => {
   ...
}

Просто ждет обещания axios.get.Этот цикл get / then работал в других запросах API без этой проблемы.Кроме того, предупреждение действительно происходит только при попытке передать ключ в объект внутри цикла for.

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

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

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Вы можете попробовать что-то простое и единственное в то время процесс:

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.log(data);
        balance[address] = data.address.balance / 100000000;
    }

    return balance;
}

Или вы можете обрабатывать все запросы параллельно с:

const result = await Promise.all(promises);
0 голосов
/ 28 ноября 2018

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

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

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.log(res.data.data);
      const data = res.data.data[addresses];
      console.log('data', data.address.balance);
      addressesBalance[addresses] = data.address.balance / 100000000;
    }).catch((error) => {
      console.log(error);
    });
  }


  let i;
  for (i = 0; i < addressRequests.length; i++) {
    await axiosRequest(addressRequests[i], addresses[i]);
    await delay();
  }

  resolve(addressesBalance);
};

, который просто перемещаетЗапрос axios в свою собственную функцию, которая затем передает запросы и адреса.

Ожидание не может работать в функции axiosRequest (), но вы все равно можете использовать его в цикле for для решения проблемы.

Это решило мою проблему, большое спасибо Teemu!

...