Как получить несколько объектов JSON с помощью цикла for в javascript

Я играл с Last.fm API и JSON, и я пытался получить лучших исполнителей пользователя по месяцам за последние 12 месяцев. Я пытался настроить цикл for для прохождения каждого месяца, а затем извлекать соответствующие данные JSON, соответствующие этому месяцу, но из того, что я могу сказать, кажется, что цикл for выполняется намного быстрее, чем вызов JSON.

Я использую javascript API last.fm Феликса Брунса https://github.com/fxb/javascript-last.fm-api

Я проверил консоль, и никаких значений месяца не было зарегистрировано, кроме 12. Я также получаю ошибку Uncaught Reference Error "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>

Любая помощь будет оценена, спасибо!


person Dennis    schedule 05.05.2013    source источник
comment
включили ли вы http://www.json.org/json2.js в скрипты на вашем страница ?   -  person soulcheck    schedule 05.05.2013
comment
@soulcheck: современные браузеры имеют встроенный глобальный JSON. Я сомневаюсь, что (возможно) отсутствие json2.js является проблемой.   -  person icktoofay    schedule 05.05.2013
comment
@icktoofay, судя по сообщению об ошибке, OP может получить   -  person soulcheck    schedule 05.05.2013
comment
также проблема OP определенно не в порядке входящих ответов, так как тогда, по крайней мере, что-то будет в журнале. Отсутствие JSON было проблемой еще в IE8 в режиме совместимости. Ааа, ссылка неудачная - эта работает   -  person soulcheck    schedule 05.05.2013
comment
с другой стороны, там тоже есть console.log, так что предлагаю что-то современное :)   -  person soulcheck    schedule 05.05.2013


Ответы (1)


getTopArtists является асинхронным, поэтому его вызов только запускает запрос; он не ждет, пока он закончится. Обратный вызов - это то, как вы узнаете, когда это будет сделано. Это означает, что ваш цикл 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. Когда это произойдет, все данные будут загружены.

person icktoofay    schedule 05.05.2013
comment
Большое спасибо! Спасибо и за пояснение, очень помогло. - person Dennis; 06.05.2013