【问题标题】:Not able to loop through returned data from api无法循环从 api 返回的数据
【发布时间】:2020-03-01 18:32:06
【问题描述】:

我有从 api 返回的数据,我正在获取该数据并将其推送到一个数组中,如果我使用来自 api 的数据控制台.log 数组,但是当我尝试循环遍历时数组,但其中没有任何内容,但正如我之前提到的,我可以控制台记录数组并且其中有数据。

我的代码是..

(()=>{
    let zips = ["98439", "90210", "18614", "98459", "85331", "30028", "17584", "12345", "34983", "48503", "934399", "17088", "94874", "93893", "23939", "34989", "79843", "34398", "03438", "93843", "34893", "43893", "90834", "93439", "17876"];
    let coordResults = [];

    for(let i = 0; i< zips.length; i++){
        fetch("https://maps.googleapis.com/maps/api/geocode/json?address=" + zips[i]+ "&key=" + GoogleAPIKEY + "")
      .then(response => {
        return response.json()
      })
      .then(data => {
        coordResults.push(data.results[0].address_components);
      })
      .catch(err => {
        // Do something for an error here
      });
    }

    console.log(coordResults);

    for(let j = 0; j < coordResults.length; j++){
        console.log(coordResults);
    }
})();

【问题讨论】:

  • 你能提供console.log(coordResults);的输出吗?

标签: javascript fetch


【解决方案1】:

这就是 promise 的工作原理,您的数据无法立即获得,因此 for 循环看不到您的数据

这是正确的解决方案

(()=>{
    let zips = ["98439", "90210", "18614", "98459", "85331", "30028", "17584", "12345", "34983", "48503", "934399", "17088", "94874", "93893", "23939", "34989", "79843", "34398", "03438", "93843", "34893", "43893", "90834", "93439", "17876"];
    let coordResults = [];

    for(let i = 0; i< zips.length; i++){
        // attach to variable
        const promise = fetch("https://maps.googleapis.com/maps/api/geocode/json?address=" + zips[i]+ "&key=" + GoogleAPIKEY + "")
      .then(response => {
        return response.json()
      })
      .then(data => {
        return data.results[0].address_components // return your proper field
      })
      .catch(err => {
        // Do something for an error here
      });

      // push promise to array, not data
      coordResults.push(promise)
    }

    console.log(coordResults); // this is list of promises, await them
    Promise
      .all(coordResults) // wait them all
      .then((results) => { // here's your list of items
        for(let j = 0; j < results.length; j++){
            const data = results[j];
            console.log(data);
        }
    })
})();

【讨论】:

    【解决方案2】:

    您的coordResults 数组开始为空,然后在您从 fetch 中收到返回的结果后,它会向其中推送多个结果。

    但是,当您循环遍历它时,这发生在异步(获取)的上下文之外,因此此时它仍然是空的。

    控制台日志显示为 not 为空的原因是因为 console.log 不是静态的。如果您输出一个对象,并且该对象稍后会更新,那么 console.log 输出也会如此。它具有误导性,但这就是它的工作原理。

    如果您将第二个 for 循环向上移动到 .then() 链中,您将看到它按预期输出。

    【讨论】:

      【解决方案3】:

      您在等待fetch 请求完成之前登录数组。所以你的数组在那个时间点总是空的。

      您应该做的是在zips 数组上使用map() 方法并将fetch 结果返回到一个新数组中。 zipFetches 将是一系列承诺。每个 promise 都是 fetch 请求的结果。

      使用Promise.all() 等待zipFetches 中的所有promise 完成,然后在控制台中显示结果。

      let zips = ["98439", "90210", "18614", "98459", "85331", "30028", "17584", "12345", "34983", "48503", "934399", "17088", "94874", "93893", "23939", "34989", "79843", "34398", "03438", "93843", "34893", "43893", "90834", "93439", "17876"];
      
      let zipFetches = zips.map(zip => fetch("https://maps.googleapis.com/maps/api/geocode/json?address=" + zip + "&key=" + GoogleAPIKEY + "")
        .then(response => response.json())
        .then(data => data.results[0].address_components));
      
      Promise.all(zipFetches).then((coordResults) => {
        console.log(coordResults);
      });
      

      【讨论】:

        猜你喜欢
        • 2017-08-06
        • 2018-09-07
        • 1970-01-01
        • 1970-01-01
        • 2022-01-22
        • 1970-01-01
        • 2021-12-07
        • 2019-09-30
        • 2021-04-22
        相关资源
        最近更新 更多