React Axios API 调用与数组循环给出错误的顺序?

Posted

技术标签:

【中文标题】React Axios API 调用与数组循环给出错误的顺序?【英文标题】:React Axios API call with array loop giving wrong order? 【发布时间】:2018-07-08 18:44:40 【问题描述】:

我正在学习 react 并使用数组进行一些 axios api 调用。我做了一个关于通过coinmarketcap api收集数据的代码来学习。

所以,我的意图是从 API 中获取带有硬编码的加密货币 ID 数组的价格,并将它们推送到价格数组中。但是我遇到了价格数组的问题,因为价格都混乱了。我应该按这个顺序得到一个数组

[比特币价格、以太坊价格、恒星价格、瑞波价格]

但是当我在浏览器中运行它时,价格是随机出现的,而不是按这个顺序排列的,有时我得到了我的订单,有时它没有。我使用了一个 onClick 调用 getPrice 方法的按钮。有谁知道我的代码出了什么问题?谢谢!

constructor()
    super();

    this.state = 
        cryptos:["bitcoin","ethereum","stellar","ripple"],
        prices:[]
    ;

    this.getPrice = this.getPrice.bind(this);




getPrice()
    const cryptos = this.state.cryptos;
    console.log(cryptos);

    for (var i = 0; i < cryptos.length; i++)       
        const cryptoUrl = 'https://api.coinmarketcap.com/v1/ticker/' + cryptos[i];

    axios.get(cryptoUrl)
        .then((response) => 
            const data = response.data[0];
            console.log(data.price_usd);

            this.state.prices.push(data.price_usd);
            console.log(this.state.prices);
        )

        .catch((error) => 
        console.log(error);
        ); 
    


【问题讨论】:

Axios 调用是异步的,因此您编写的代码并不能保证您会按照创建它们的顺序完成它们。 【参考方案1】:

如果您想按照您进行异步调用的顺序接收数据,您可以使用Promise.all,它会一直等待直到数组的所有承诺都被执行并被解析,并按照它们的顺序返回值执行。

const cryptos = ['bitcoin', 'ethereum', 'stellar', 'ripple'];
const arr = [];
for (var i = 0; i < cryptos.length; i++)       
    const cryptoUrl = 'https://api.coinmarketcap.com/v1/ticker/' + cryptos[i];
    arr.push(axios.get(cryptoUrl));


Promise.all(arr).then((response) =>
  response.map(res => console.log(res.data[0].name, res.data[0].price_usd))
).catch((err) => console.log(err));

【讨论】:

【参考方案2】:

您可以在 for 循环中使用闭包来捕获 i 的值,并在返回数据后将其用作索引,而不是使用 push:

getPrice()
    const cryptos = this.state.cryptos;
    console.log(cryptos);

    for (var i = 0; i < cryptos.length; i++) 
        const cryptoUrl = 'https://api.coinmarketcap.com/v1/ticker/' + cryptos[i];
        (function (x) 
            axios.get(cryptoUrl)
                .then((response) => 
                    const data = response.data[0];
                    console.log(data.price_usd);

                    var newPrices = this.state.prices;
                    newPrices[x] = data.price_usd;
                    this.setState(prices: newPrices); 
                    console.log(this.state.prices);
                )
                .catch((error) => 
                    console.log(error);
                );
        )(i);
    

【讨论】:

以上是关于React Axios API 调用与数组循环给出错误的顺序?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 React 中,我的 axios API 调用有 Authorization Header,其中包含 Bearer <token> 但未被授权并给出 401 错误

如何使用 Axios 通过 React 发出循环请求?

React - 多个 Axios 请求

React Hook useEffect :使用 axios 和 async await .api 获取数据,调用连续相同的 api

React 原生调用 API axios 网络

将从 api 接收到的数据格式化为数组 React Axios