I'm fully aware that getJSON runs asynchronously however I'm having trouble understanding why my program is always returning the same data. I'm looping through a list of possible sites to query and using getJSON to return data then manipulating the data however on each iteration of my loop the data that I'm getting back seems to be the same. When running this code directly I get the expected value (not in a loop). There have been odd occasions when I've received the second or third set of data however I'm assuming that this is caused by the network being faster than usual.
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;
}));
}
Your code says this:
$.when.apply(...)
)songList
arrayhttp://api.jquery.com/jQuery.when/
In the case where multiple Deferred objects are passed to jQuery.when(), the method returns the Promise from a new "master" Deferred object that tracks the aggregate state of all the Deferreds it has been passed. The method will resolve its master Deferred as soon as all the Deferreds resolve
Each one of your asynchronous operations goes
songList
arraysongList
arraySo therefore your flow is going to go (for example; order may vary)
songList
, add list 1 to songList
songList
, add list 2 to songList
songList
, add list n to songList
songList
i.e. whichever asynchronous operation happens to execute last clears out whatever was in there before and adds just its list.
If you really want to stick to using your global songList
variable, instead of clearing it out in each runJSON invocation, you could clear it out before the loop and then just append all the results into a long list. Or to keep them separate, have it as an array of arrays (for example).