【问题标题】:Cannot access specific data inside array of objects无法访问对象数组中的特定数据
【发布时间】:2021-11-08 00:38:22
【问题描述】:

我无法访问数组中的特定对象。我将数据从 api 推送到数组。当我控制台日志国家Arr 它显示对象的所有属性的完整数组,但是当我尝试访问特定索引中的特定对象时,我得到未定义。此外,它应该返回一个数组,但 typeof 显示它是一个对象?有人可以帮忙吗?

const countriesURL = 'https://restcountries.eu/rest/v2/all';
let countriesArr = [];

async function getCountriesData() {
const response = await fetch(countriesURL);
const data = await response.json();
showCountries(data);
}

function showCountries(countries) {
    countries.forEach((country) => {
        countriesArr.push(country)
})}

console.log(countriesArr)          //this shows array of objects
console.log(countriesArr[0])       //this shows undefined????

【问题讨论】:

  • 您在哪里/何时调用您的函数?这看起来像是异步混淆,但在不知道实际调用顺序的情况下,几乎没有什么帮助
  • 我在这里写的 showCountries 函数只是实际函数的一部分。 showCountries 在 dom 中显示数据,这很有效。同时我想创建一个包含所有数据的数组,这样我就可以对其进行排序或过滤。我在页面底部调用 getCountriesData(),在全局范围内

标签: javascript arrays object async-await


【解决方案1】:

试试这样:

const countriesURL = 'https://restcountries.eu/rest/v2/all';
let countriesArr = [];

async function getCountriesData() {
  const loading = document.createElement("P");
  loading.innerText = 'Loading ...'
  document.body.appendChild(loading);
  await fetch(countriesURL)
    .then(response => response.json())
    .then(data => countriesArr = data)
    
    loading.remove();
    console.log(countriesArr)  
    console.log(countriesArr[0])  
}

getCountriesData()

【讨论】:

    【解决方案2】:

    您的主要问题是异步获取数据,因此您向服务器发出请求,在它发出请求时,您的下一个代码正在完成

     getCountriesData() is loading...
     showCountries(countries) complete!
     console.log(countriesArr) complete!
     console.log(countriesArr[0]) complete!
    

    在这种情况下国家数组是空的,当你取不存在的[0]元素时,JS返回'undefined'。

    尝试使用 Promise API 来避免这种情况:

    const countriesURL = 'https://restcountries.eu/rest/v2/all';
            let countriesArr = [];
    
            async function getCountriesData() {
                const response = await fetch(countriesURL);
                const data = await response.json();
                showCountries(data);
            }
    
            function showCountries(countries) {
                countries.forEach((country) => {
                    countriesArr.push(country)
                })
            }
            
            /* this function return special type Promise */
            getCountriesData().then(res => {
                console.log(countriesArr)
                console.log(countriesArr[0])
            })

    【讨论】:

      【解决方案3】:
      const countriesURL = 'https://restcountries.eu/rest/v2/all';
      let countriesArr = [];
      
      async function getCountriesData() {
        const response = await fetch(countriesURL);
        const data = await response.json();
        showCountries(data);
      }
      
      function showCountries(countries) {
          countries.forEach((country) => {
            countriesArr.push(country)
      })}
      
      getCountriesData();
      
      console.log(countriesArr)          //this shows array of objects
      console.log(countriesArr[0])       //this shows undefined????
      

      JavaScript 是单线程的——无论是在浏览器还是 NodeJS 中运行。因此,当浏览器处理您的代码时,它将自顶向下处理并评估起始文件中的变量,然后继续将所有函数放入调用堆栈中。

      当浏览器引擎遇到一个异步函数时,它会获取对该函数的引用并将该函数放入回调队列中,如果它是一个承诺(因为它只是一个承诺的包装器,所以它被放入)进入“作业队列”/“微任务队列”。一旦异步函数发出完成事件,浏览器引擎就会获取该数据并将该函数与其引用一起推送到调用堆栈中,以便在堆栈中的所有当前任务/函数完成后运行。函数引用包含行号,因此引擎知道在哪里评估函数。

      所以知道了这一点,当你到达 getCountriesData() 时,这个异步函数会从主线程中弹出,并放入一个单独的队列中,其中包含专用于网络相关任务的线程,程序执行会立即处理和评估以下控制台在 getCountriesData() 完成执行之前记录日志。

      确保您将从 getCountriesData() 收到的数据正确插入/操作到 countriesArr 的唯一方法是,您是否在该函数本身或 then() 中执行所有与数据相关的任务继续。

      【讨论】:

      • 谢谢你的回答,现在我明白了
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-13
      • 1970-01-01
      • 2019-06-13
      • 2021-09-24
      • 2020-08-14
      • 1970-01-01
      相关资源
      最近更新 更多