Processing a collection of objects, one at a time, with an asynchronous method.
You're basically there, I would say. If the validateSongById function works as  expected, it'll call its callback when it's done, and you then do it again for the next video.

function processVideos(videos, callback) {
    var results = [], i = 0;
    function processNext() {
        if(i &lt; videos.length) {
            validateSongById(videos[i].videoId, function (result) {
                results.push(result);
                i++;
                processNext();
            });
        } else {
            callback(results); // when called, all the videos have been processed
        }
    }
    processNext(); // start the processing
}


With this, you call processVideos with the videos array and a callback. The callback is called with a new array of all the results.

Alternatively, you can attach the result to the video-object directly, so the video and the result are tied together:

function processVideos(videos, callback) {
    var i = 0;
    function processNext() {
        if(i &lt; videos.length) {
            validateSongById(videos[i].videoId, function (result) {
                videos[i].result = result;
                i++;
                processNext();
            });
        } else {
            callback(); // when called, all the videos have been processed
        }
    }
    processNext(); // start the processing
}