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 の仕組みでは、非常に多くの重複が返されます。たとえば、「天国への階段」と「天国への階段」は 2 つの別個の曲と見なされます。

この問題を回避するために、すべての曲に固有の各曲の「hotttnesss」値を使用しています。同じアーティストによる 2 つの曲が同じホットさを持つことができる唯一の方法は、これらの重複の場合のように、それらが実際に同じ曲である場合です。

そのため、報告された曲の数が 10 未満である間に、返された各曲をステップ実行し、その hotttness 値が既に報告された曲の hotttness 値の配列に含まれていない場合は曲を報告しています。曲を報告した後、その曲のホットネス値が配列に追加されます。

4

1 に答える 1

5

は、ループの後ではなく、ループの内側i++;にある必要があります。また、ajax コールバックで を設定し、同じループを に制限する必要があります。whilei0i < 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']プロパティ名が数字で始まるか、JavaScript の識別子名として無効な文字を含んでいる場合を除き、引用符で囲む必要はありませんsong.hotttnessresponse['songs']response.songs

  3. ()ほとんどの場合、関数呼び出しを配置し​​ても目的はありません。

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

    より明確に

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

    (それらに目的があるのは、インラインで呼び出される関数式を含む場合のみです。)

  4. isInArray関数は必要ありません。jQuery には既に次の 1 つがあります: $.inArray. (jQuery API を最初から最後まで読むのは時間の価値があります。文字通り 1 時間か 2 時間しかかからず、知らないかもしれないあらゆる種類の便利な情報を見つけることができます。)

于 2016-01-04T07:43:23.803 に答える