2014-11-13 1 views
0

Я полностью понимаю, что getJSON работает асинхронно, однако мне трудно понять, почему моя программа всегда возвращает одни и те же данные. Я просматриваю список возможных сайтов для запроса и использования getJSON для возврата данных, а затем манипулирования данными, однако на каждой итерации моего цикла данные, которые я возвращаю, кажутся одинаковыми. При запуске этого кода я получаю ожидаемое значение (не в цикле). Были случаи, когда я получил второй или третий набор данных, однако я предполагаю, что это вызвано тем, что сеть работает быстрее обычного.getJSON running order

var songObj; 

for(i = 0; i < networks.length; i++) 
{ 
    runJSON(networks[i],"track",false); 

    songObj = []; 

    $.when.apply($, deferreds).then(function() { 
     songObj = ($.grep(songList, function(e){return e.artist == curSong[0].artist})); 
     console.log(songList); 
     imgCode = "<a href='" + songObj[0].link 
       + "'><img id = 'spotifyLogo' src='images/spotify.jpg' alt='mIage'></a>"; 
     theValue = imgCode + "<br>" 
       + "Available on Spotify for " + songObj[0].price 
       + "<br> <br>"; 

     $("#songDisplay").append(theValue); 
     deferreds = [], index; 
    }); 
} 

function runJSON(network,searchType,display){ 
    var URL = returnURL(network,searchType,$('#song_field').val().split(' ').join("+")); 

    var val = $('#song_field').val(); 
    var data = {val: val} 

    deferreds.push($.getJSON(URL, data, function(data){ 

     if(document.getElementById("box") !== "undefined" && display == true){ 
      clearScreen(); 
      createCols(); 
     } 

     songList = []; 
     eval(network + "(data);"); 

     if(display === true){ 
      for(i = 0; i < songList.length; i++) 
      { 
       displayTrack(i); 
      } 
     } 

     done = true; 

    })); 
} 
+0

Глобальный 'songList', установленный в каждом обработчике успеха' runJSON', касается меня (или если бы что-нибудь было добавлено к нему, я предполагаю, что вы удалили какой-то код, который это делает). Есть все шансы, что все обработчики 'getJSON' будут выполняться до запуска любого из обработчиков' then() '.Все эти обработчики получат одинаковые (последние) значения 'songList'. –

+0

@PaulRoub Вы правы в том, что последние значения songList всегда возвращаются. Код, который добавляет к songList, находится в displayTracks(), который я не копировал, потому что я не был уверен, что это актуально, это существенно толкает данные, которые я хочу из json в объект. Почему это будет проблемой? –

ответ

0

Ваш код говорит, что это:

  1. Начните кучу асинхронных операций
  2. Дождитесь их всех, чтобы завершить ($.when.apply(...))
  3. Процесс, в котором songList массив

http://api.jquery.com/jQuery.when/

В случае, когда несколько переданных объектов передаются в jQuery.when(), метод возвращает Promise из нового «основного» объекта отложенного объекта, который отслеживает состояние агрегата всех переданных отсрочек. Метод разрешит хозяин Отложенный как только все Deferreds решить

Каждый из ваших асинхронных операций идет

  1. зачистить songList массив
  2. Добавьте некоторые данные в songList массиве

Таким образом, ваш поток будет идти (например, заказ может отличаться)

  • Убирайтесь songList, добавить список 1 к songList
  • очистить songList, добавить список 2 к songList
  • ...
  • очистить songList, добавить список п к songList
  • Процесс songList

т. Е. Какая бы асинхронная операция не выполнялась, последняя очищает все, что было там раньше, и добавляет только ее список.

Если вы действительно хотите использовать свою глобальную переменную songList, вместо ее очистки в каждом вызове runJSON вы можете очистить ее до цикла, а затем просто добавить все результаты в длинный список. Или, чтобы сохранить их отдельно, используйте его как массив массивов (например).

+0

Я не могу поверить, насколько это было просто, спасибо вам много! Я весь день бил головой об этом и никуда не уходил. –