与API接口时,$(document)中的无限循环已就绪

Infinite loop in $(document).ready when interfacing with API

本文关键字:无限循环 就绪 document 接口 API      更新时间:2023-09-26

我在这个项目中使用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);
});

代码简介:

当我点击页面的某个部分(稍后将扩展为用户输入的艺术家)时,我正试图获得齐柏林飞艇乐队的前十首歌曲。但按照EchoNest API的工作方式,会返回很多重复项。例如,《天堂的阶梯》和《天堂的楼梯》被认为是两首独立的歌曲。

为了解决这个问题,我使用了每首歌的"hotttnesss"值,这对每首歌来说都是独一无二的。同一艺术家的两首歌曲能够具有相同的热度的唯一方法是,如果它们实际上是同一首歌,就像这些重复的歌曲一样。

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

i++;应该在while循环内,而不是在它之后。您还需要在ajax回调中将i设置为0,并将同一循环限制为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. 函数声明(例如getMusic)不是语句,它们后面不需要语句终止符(;)。(在函数表达式之后执行,比如说,这是赋值的一部分。)

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

  3. 在大多数情况下,将()放在函数调用周围没有任何作用,因此

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

    可以更清楚地是

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

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

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