【问题标题】:Don't make functions within a loop no-loop-func Axios Request async await不要在循环中创建函数 no-loop-func Axios 请求异步等待
【发布时间】:2025-12-17 23:05:02
【问题描述】:

我有一个 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.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]];

addresses 只是一个字符串数组。当我从对象 res.data.data 中删除访问关键地址 [i] 时,警告消失了。控制台中的对象 res.data.data 是:

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

所以莱特币地址 LWcXUB6ny88tK49TK1V6KprE5oDcJ1zJhx 是一个对象中的键,值是另一个以地址和交易为键的对象。我的最终目标是地址键值的平衡。

我在下面留下了一个注释 for 循环(用于稍微不同的 api),因为我没有在那个循环中收到警告。问题是,如果没有通常访问对象中密钥的方式,就无法访​​问莱特币地址密钥的值。

我改变了这一行:

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

收件人:

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

我一尝试 Object.keys 就会收到错误消息,更不用说实际访问第一个键了:

address[0]

这让我完全不知所措,因为我实际上无法访问对象而不会收到我在函数中使用循环的错误。

resolve 和 reject 来自调用此函数的承诺,我使用 async 函数等到所有 api 请求完成后再解决此函数所在的承诺。

然后那个承诺就会消失并正确设置我的状态。

有人有什么想法吗?我查看了许多其他 SO,但似乎没有人处理我在这里的问题。老实说,我根本看不出我是如何在循环中使用函数的。

访问对象中的键当然不是我所知道的函数。

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

只是在等待 axios.get 的承诺。此 get / then 循环在其他 api 请求中有效,没有此问题。此外,警告实际上仅在尝试将键传递给 for 循环内的对象时才会发生。

我应该让您知道,在警告的情况下一切正常。我无法摆脱这个警告,这让我很生气。

非常感谢您的时间和洞察力。

【问题讨论】:

  • 在循环外声明函数,并将引用放在then的参数上。或者在 linter 的配置中选择退出 no-loop-func
  • 如果我在 for 循环之外声明我的异步函数,我不能在 for 循环中使用 await,那么可以吗?或者你是说把 axios 请求放在循环外的一个函数中然后调用它?

标签: javascript ecmascript-6 async-await axios es6-promise


【解决方案1】:

你可以在当时尝试一些简单而单一的过程:

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);

【讨论】:

  • 哦,好点也与 await delay() 承诺功能,但这样我就可以保持在请求限制以下。如果没有延迟,这可能会比 api 愿意让我根据响应速度执行请求的速度更快。感谢您的回答!
【解决方案2】:

根据 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 请求移动到它自己的函数中,然后传递请求和地址。

await 不能在 axiosRequest() 函数中工作,但您仍然可以在 for 循环中使用它来解决问题。

这解决了我的问题,非常感谢 Teemu!

【讨论】: