javascript - 与 API 交互时 $(document).ready 中的无限循环

标签 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);
});

代码简要说明:

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

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

因此,当报告的歌曲数量低于 10 首时,我将逐步遍历每首返回的歌曲,如果该歌曲的 hotttness 值不在已报告歌曲的 hotttness 值的数组中,则报告该歌曲。上报歌曲后,将歌曲的hotttnesss值添加到数组中。

最佳答案

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'])
            }
        }
    });
}

或者我就使用Array#forEach (如果需要支持IE8可以shim):

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. 函数声明(例如您的 getMusic )不是语句,您不需要在它们后面添加语句终止符( ; )。 (您可以在函数表达式之后执行,该函数是赋值的一部分。)

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

  3. 输入 () 没有任何意义。在大多数情况下,围绕函数调用,所以

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

    可以更清楚

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

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

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

关于javascript - 与 API 交互时 $(document).ready 中的无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34586608/

相关文章:

javascript - Vuejs 计算属性依赖于其他异步计算属性

c true循环语句在hangman中不断实现

javascript - 如何删除元素父元素的下一个 div?

javascript - 如何阻止 Google reCAPTCHA 显示警报?

javascript - 单击事件时提醒元素属性

javascript - 如何在javascript中制作定时队列

javascript - jQuery 自动完成 : [Object object] showing instead of value

python - 'if not in' 时间复杂度

php - 选择比较另一个表中的字段的记录

JavaScript 函数关键字在声明式使用时似乎已准备好?