首页 > 解决方案 > 反应原生,无法访问数组中的元素

问题描述

我在访问本机数组中的元素时遇到了一点问题。我有以下代码的问题:

GetStockPrice = () => {
  var stockPrice = StockLogic.getStockPrice();
  console.log(stockPrice)
  for (let index = 0; index < stockPrice.length; index++) {
    console.log(stockPrice[index]);
  }
};

StockLogic.getStockPrice() 看起来像这样:

getStockPrice() {
  var stockPricesJSON = [];
  this.stocknames.forEach(stock => {
    var url =
      "https://api.iextrading.com/1.0/stock/" +
      stock +
      "/batch?types=quote,news,chart&range=1m&last=10";
    fetch(url)
      .then(resp => resp.json())
      .then(data =>
        stockPricesJSON.push(
          [data.quote.symbol, data.quote.open, data.quote.close, Number(((data.quote.open - data.quote.close)).toFixed(1))]
        )
      );
  });
  return stockPricesJSON;
}

如果我运行 GetStockPrice 函数,我只会得到从其他类传递的 stockPrice 的 console.log()。但是循环中的日志没有显示出来。

我想问题出在 StockLogic 中,但我无法弄清楚。我希望你能再次帮助我。希望你拥有美好的一天。艾文

标签: reactjsreact-native

解决方案


因为fetchforEach都是异步的,stockPricesJSON所以作为空数组返回。

对于这样的事情,你会想要使用Promise.all

function getStockPrice() {
  var stockPricesJSON = [];
  var promises = this.stocknames.map(stock => {
    var url =
      "https://api.iextrading.com/1.0/stock/" +
      stock +
      "/batch?types=quote,news,chart&range=1m&last=10";
    return fetch(url);
  });
  Promise.all(promises).then(function(stocks) {
      stocks.forEach(function(stock) {
          //...your code
      })
  })
}

请注意,您可能需要调用 Promise.all 两次,这可能看起来像这样:

Promise.all(promises).then(function(stocks) {
  var jsonpArr = stocks.map(function(stock) {
    return stock.jsonp();
  });
  Promise.all(jsonpArr).then(function(stocks) {
    stocks.forEach(function(stock) {
      //...your code here
    });
  });
});

最后,我建议您使用 redux 或组件状态存储它,而不是返回该值setState。如果这个函数不属于一个组件,那么我建议将整个东西包装在一个承诺中

new Promise(function(resolve, reject) {
   //...your code
})

并调用resolve()结果

为了进一步改善这一点,我强烈建议使用async/await更现代的语法

const getStockPrice = () => {
  return new Promise( async (resolve, reject) => {
    try {
      let promises = this.stocknames.map(stock => {
        var url =
        "https://api.iextrading.com/1.0/stock/" +
        stock +
        "/batch?types=quote,news,chart&range=1m&last=10";
        return fetch(url)
      })
      let result = await Promise.all(promises)
      let stocks = await Promise.all(result.map(r => r.jsonp()))
      stocks.forEach(stock => {
        //...your code
        resolve(result)
      })
    } catch(e) {
      reject(e)
    }
  })
}

和往常一样,文档是您的朋友!

承诺.all()

异步/等待


推荐阅读