与API接口时$(document).ready中的无限循环

kha*_*263 0 javascript jquery loops echonest

我在这个项目上使用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);
});
Run Code Online (Sandbox Code Playgroud)

代码简要说明:

当我点击页面的某个位置(后来扩展为用户输入的艺术家)时,我正试图获得Led Zeppelin的前10首歌曲.但是Echo Nest API的工作方式,返回了许多重复项.例如,"天堂的阶梯"和"天堂的阶梯"被认为是两首独立的歌曲.

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

因此,当报告的歌曲数量低于10时,我将逐步浏览每首返回的歌曲,如果其热点值不在已报告歌曲的hotttnesss值的数组中,则报告该歌曲.报告歌曲后,歌曲的hotttnesss值将添加到阵列中.

T.J*_*der 5

i++;应是内部while循环,之后吧.您还需要设置i0你的Ajax回调,并限制同一回路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'])
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

或者我只是使用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'])
            }
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

附注:

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

  2. song['hotttnesss']可以写song.hotttness,response['songs']response.songs,等.除非属性名以数字开头或包含的字符,是不是在JavaScript标识符名称有效,没有必要引用它.

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

    if (!(isInArray(song['hotttnesss'], hotArray))) {
    
    Run Code Online (Sandbox Code Playgroud)

    可能更清楚

    if (!isInArray(song['hotttnesss'], hotArray)) {
    
    Run Code Online (Sandbox Code Playgroud)

    (只有当它们有目的时才涉及内联调用的函数表达式.)

  4. 你不需要你的isInArray功能; jQuery已经有一个:$.inArray.(非常值得花时间阅读jQuery API开始结束.字面上只需要一两个小时,你会发现各种有用的东西,你可能不知道.)