0

我在这个项目上使用 CodePen,这就是我发现我的代码中有一个无限循环的方式。顺便说一句 - 它估计无限循环的行号为第 0 行,这就是为什么我怀疑它与这段$(document).ready()代码有关。

我是 jQuery / API 初学者,如果这很明显,我深表歉意。

这是代码:

$(document).ready(function() {
  var key = '*****************';
  var i = 0;
  var hotArray = [];

  function isInArray(value, array) {
    return array.indexOf(value) > -1;
  }

  function getMusic() {
    $.getJSON('http://developer.echonest.com/api/v4/song/search?api_key=' + key + '&artist=led+zeppelin&sort=song_hotttnesss-desc&results=50&bucket=song_hotttnesss', function(data) {
      while ($('.songs li').length < 10) {
        if (!(isInArray(data.response['songs'][i]['hotttnesss'], hotArray))) {
          $('.songs').append('<li>' + data.response['songs'][i]['title'] + '</li>');
          hotArray.push(data.response['songs'][i]['hotttnesss'])
        }
      }
      i++;
    });
  };

  $('.click').click(getMusic);
});

代码简要说明:

当我点击页面的某个位时,我试图获得 Led Zeppelin 的前 10 首歌曲(稍后将扩展到用户输入的艺术家)。但是 Echo Nest API 的工作方式会返回很多很多重复项。例如,“Stairway to Heaven”和“Stairway To Heaven”被认为是两首独立的歌曲。

为了解决这个问题,我使用了每首歌曲的“hotttnesss”值,这对于每首歌曲都是独一无二的。同一艺术家的两首歌曲可以具有相同的热度的唯一方法是它们实际上是同一首歌曲,就像这些重复的情况一样。

因此,当报告的歌曲数量低于 10 时,我将逐步浏览每首返回的歌曲,并在其 hotttnesss 值不在已报告歌曲的 hotttnesss 值数组中时报告该歌曲。报告歌曲后,将歌曲的 hotttnesss 值添加到数组中。

4

1 回答 1

5

i++;应该循环内,而不是在while循环之后。您还需要在 ajax 回调中设置i0,并将相同的循环限制为i < data.response['songs'].length.

例如:

function getMusic() {
    $.getJSON('http://developer.echonest.com/api/v4/song/search?api_key=' + key + '&artist=led+zeppelin&sort=song_hotttnesss-desc&results=50&bucket=song_hotttnesss', function(data) {
        var i, songs = data.response['songs'];
        for (i = 0; $('.songs li').length < 10 && i < songs.length; ++i) {
            if (!(isInArray(songs[i]['hotttnesss'], hotArray))) {
                $('.songs').append('<li>' + songs[i]['title'] + '</li>');
                hotArray.push(songs[i]['hotttnesss'])
            }
        }
    });
}

或者我只是使用Array#forEach(如果你需要支持 IE8,你可以填充它):

function getMusic() {
    $.getJSON('http://developer.echonest.com/api/v4/song/search?api_key=' + key + '&artist=led+zeppelin&sort=song_hotttnesss-desc&results=50&bucket=song_hotttnesss', function(data) {
        data.response['songs'].forEach(function(song) {
            if (!(isInArray(song['hotttnesss'], hotArray))) {
                $('.songs').append('<li>' + song['title'] + '</li>');
                hotArray.push(song['hotttnesss'])
            }
        });
    });
}

旁注:

  1. 函数声明(例如 your getMusic)不是语句,在它们之后不需要语句终止符 ( ;)。(你在一个函数表达式之后做,比如说,一个赋值的一部分。)

  2. song['hotttnesss']可以写成song.hotttness, response['songs']asresponse.songs等。除非属性名称以数字开头或包含在 JavaScript 标识符名称中无效的字符,否则不需要引用它。

  3. ()在大多数情况下,通过调用函数没有任何目的,所以

    if (!(isInArray(song['hotttnesss'], hotArray))) {
    

    可以更清楚地是

    if (!isInArray(song['hotttnesss'], hotArray)) {
    

    (它们有目的的唯一时候涉及内联调用的函数表达式。)

  4. 你不需要你的isInArray功能;jQuery 已经有一个:$.inArray. (花时间从头到尾通读 jQuery API 非常值得。实际上只需要一两个小时,你会发现各种你可能不知道的有用的东西。)

于 2016-01-04T07:43:23.803 回答