How to retrieve multiple JSON objects with a for loop in javascript

ぃ、小莉子 提交于 2019-12-25 07:29:34

问题


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!


回答1:


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.



来源:https://stackoverflow.com/questions/16380714/how-to-retrieve-multiple-json-objects-with-a-for-loop-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!