I think that async library would suit perfect here.
$.ajax({
url:'mysite.it/ajax/list_filter.php',
data:data,
type:'POST'
}).done(function(data){
var response = $.parseJSON(data);
var people = $('<ul />');
if(response.success && response.showcase) {
async.map(response.showcase, function(item, done) {
var img = new Image();
//we now install callbacks to certain events
img.addEventListener('load', function () {
done(null, {
img: img,
username: item.username
});
});
img.addEventListener('error', function () {
done(true);
});
//this will kick image loading
img.src = 'http://mysite.it/pict_thumbs/' + item.pool_user_pict;
}, function (err, results) {
if(err) {
//images weren't loaded correctly, handle this whatever you like
console.error('Something went wrong');
return;
}
//here you now know that every image you wanted is loaded
results.forEach(function (data) {
var li = $('<li />');
li.append(data.img);
li.append($('<label />', {
html: data.username
}));
people.append(li);
});
});
}
});
Method async.map
which I used works in the way that it invokes it's second argument (the iterator) on each element of the array and then wait until all the done
functions were called. done
function is a function that gets an error as its first argument (null
if there was no error) and a result of an asynchronous operation - in our case, a loaded image element, which is pushed to a new array.
When all the done
s have been called, async then calls a third argument (the callback), passing it an error (or null
if there was no error) and an array, created from all the asynchronous callbacks. Then we can just iterate over them and append the images and usernames to the html element.
Here is fiddle that demonstrates it (using fake data, saved in the response
variable): http://jsfiddle.net/wxx6veqb/