如何使用JavaScript中的for循环检索多个JSON对象 [英] How to retrieve multiple JSON objects with a for loop in javascript

查看:112
本文介绍了如何使用JavaScript中的for循环检索多个JSON对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用Last.fm API和JSON,在过去的12个月中,我一直在尝试按月检索用户的顶级歌手.我试图设置一个for循环以每月进行一次,然后提取与该月相对应的相关JSON数据,但是据我所知,似乎for循环的运行速度比JSON调用快得多.

我正在使用Felix Bruns的last.fm javascript API https://github.com. com/fxb/javascript-last.fm-api

我检查了控制台,除12外,没有记录月份的值.我还收到了未捕获的参考错误"json ## ....未定义"

我尝试寻找解决方案,但是我所有的搜索结果都是如何遍历API调用的结果,而我正在寻找如何编写一个检索多个JSON对象的循环.

<script type="text/javascript">

  var apiKey = "b0da1774db3d010f62b11f67c4de0667";
  var secret = "0baa4b10c807acc847128599680679a7";

  var lastfm = new LastFM({
    apiKey : apiKey,
    secret : secret,
    cache : undefined
  });

  var lastfm_2 = new LastFM({
    apiKey : apiKey,
    secret : secret,
    cache : undefined
  });

  $(document).ready(function() {
    $("#submit").click(function() {
      var username = $("#username").val();
      var text = "";
      if (username) {
        $("#title").html("Your Most Played Artist by Month");
        $("#title").css("color", "#222");
        // Get top artists for each month
        var topArtistsByMonth = new Array();
        for (var month = 0; month < 12; month++) {
          lastfm.user.getTopArtists({user: username, period: "1month", limit: 15, page: month + 1}, {success: function(data) {
            topArtistsByMonth.push(data.topartists);
            console.log("Month " + month + ": " + data.topartists);
          }});
        }
      } else {
        alert("No username");
      }
    });
  });

</script>

任何帮助将不胜感激,谢谢!

解决方案

getTopArtists是异步的,因此仅调用 starts 即可;它不等待它完成.回调是您如何知道何时完成的.这意味着您的for循环将它们并行触发,然后在完成后收集结果.但是,由于它们可以按任何顺序完成,因此不能保证topArtistsByMonth可以按任何顺序进行.要解决此问题,您可能希望使用显式索引而不是使用push:

for(var month = 0; month < 12; month++) {
    // We need to use an anonymous function to capture the current value of month
    // so we don't end up capturing the reference to month that the for loop is
    // using (which, by the time the callbacks complete, will always be 12.)
    (function(month) {
        lastfm.user.getTopArtists({user: username, period: "1month", limit: 15, page: month + 1}, {success: function(data) {
            topArtistsByMonth[month] = data.topartists;
            console.log("Month " + month + ": " + data.topartists);
        }});
    })(month);
}

如果您想知道何时下载了所有数据,则需要另一个变量来跟踪到目前为止已完成的数据.每次调用回调时,您都需要对其进行递增,并查看其是否达到12.完成后,所有数据均已下载.

I've been playing around with the Last.fm API and JSON and I've been trying to retrieve a user's top artists by month for the past 12 months. I tried to set up a for loop to go through each month and then pull the relevant JSON data corresponding to that month, but from what I can tell it seems like the for loop is being run through much quicker than the JSON call.

I'm using Felix Bruns' last.fm javascript API https://github.com/fxb/javascript-last.fm-api

I checked the console and no values of month were logged except for 12. I'm also getting an Uncaught Reference Error "json##.... is not defined"

I tried looking around for solutions but all of my search results came up as how to loop through the results of an API call whereas I'm looking for how to write a loop that retrieves multiple JSON objects.

<script type="text/javascript">

  var apiKey = "b0da1774db3d010f62b11f67c4de0667";
  var secret = "0baa4b10c807acc847128599680679a7";

  var lastfm = new LastFM({
    apiKey : apiKey,
    secret : secret,
    cache : undefined
  });

  var lastfm_2 = new LastFM({
    apiKey : apiKey,
    secret : secret,
    cache : undefined
  });

  $(document).ready(function() {
    $("#submit").click(function() {
      var username = $("#username").val();
      var text = "";
      if (username) {
        $("#title").html("Your Most Played Artist by Month");
        $("#title").css("color", "#222");
        // Get top artists for each month
        var topArtistsByMonth = new Array();
        for (var month = 0; month < 12; month++) {
          lastfm.user.getTopArtists({user: username, period: "1month", limit: 15, page: month + 1}, {success: function(data) {
            topArtistsByMonth.push(data.topartists);
            console.log("Month " + month + ": " + data.topartists);
          }});
        }
      } else {
        alert("No username");
      }
    });
  });

</script>

Any help would be appreciated, thanks!

解决方案

getTopArtists is asynchronous, so calling it only starts the request; it doesn't wait for it to finish. The callback is how you know when it's done. That means that your for loop fires them all off in parallel, and then you collect the results when you're done. However, since they can finish in any order, topArtistsByMonth is not guaranteed to be in any sort of order. To fix that, you'll probably want to make it use explicit indices rather than using push:

for(var month = 0; month < 12; month++) {
    // We need to use an anonymous function to capture the current value of month
    // so we don't end up capturing the reference to month that the for loop is
    // using (which, by the time the callbacks complete, will always be 12.)
    (function(month) {
        lastfm.user.getTopArtists({user: username, period: "1month", limit: 15, page: month + 1}, {success: function(data) {
            topArtistsByMonth[month] = data.topartists;
            console.log("Month " + month + ": " + data.topartists);
        }});
    })(month);
}

If you want to know when all the data has been downloaded, you'll need another variable to keep track of how many have finished so far. Every time the callback is called, you'll need to increment that and see if it's hit 12 yet. When it has, all the data has been downloaded.

这篇关于如何使用JavaScript中的for循环检索多个JSON对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆