Бесконечный цикл в $(document).ready при взаимодействии с API
Я использую 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);
});
Краткое объяснение кода:
Я пытаюсь получить топ-10 песен Led Zeppelin, когда нажимаю на определенный кусочек страницы (позже, чтобы перейти к исполнителю, введенному пользователем). Но, как работает API Echo Nest, возвращается множество дубликатов. Например, "Лестница на небеса" и "Лестница на небеса" считаются двумя отдельными песнями.
Чтобы обойти эту проблему, я использую значение "hotttnesss" каждой песни, которое уникально для каждой песни. Единственный способ, которым две песни одного исполнителя могут иметь одинаковую горячую текстуру, - это если они на самом деле одна и та же песня, как в случае с этими дубликатами.
Итак, я перебираю каждую из возвращенных песен, пока число сообщаемых песен меньше 10, и сообщаю о песне, если ее значение hotttnesss не входит в массив значений hotttnesss уже сообщенных песен. После сообщения о песне значение hotttnesss песни добавляется в массив.
1 ответ
i++;
должен быть внутри while
цикл, а не после него. Вам также нужно установить i
в 0
в вашем обратном вызове 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):
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'])
}
});
});
}
Примечания стороны:
Объявления функций (например, ваш
getMusic
) не являются утверждениями, вам не нужен терминатор операторов (;
) после них. (Вы делаете после выражения функции, скажем, часть назначения.)song['hotttnesss']
можно написатьsong.hotttness
,response['songs']
какresponse.songs
и т. д. Если имя свойства не начинается с цифры или не содержит символ, который недопустим в именах идентификаторов JavaScript, нет необходимости указывать его в кавычках.Там нет цели служить
()
вокруг вызова функции в большинстве случаев, такif (!(isInArray(song['hotttnesss'], hotArray))) {
может быть более четко
if (!isInArray(song['hotttnesss'], hotArray)) {
(Единственные случаи, когда у них есть цель, включают выражения, вызванные встроенными функциями.)
Вам не нужно ваше
isInArray
функция; У jQuery уже есть один:$.inArray
, (Стоит потратить время на изучение API jQuery, начиная с конца и до конца. Буквально через час или два вы найдете все виды полезных вещей, о которых вы, возможно, не знаете.)