これまでの調査に基づいて、async.each を正しく使用していると思います。一番下の関数 addToPlaylist は一番上の関数 getPerformances を呼び出します。addToPlaylist の最後のコールバックが呼び出されない理由と、それを修正する方法を理解しようとしています。ありがとう!
var getPerformances = function(playlist, performances, add){
var deferred = Q.defer();
var tracks = [];
async.each(performances.performance, function(performance, cb) {
getSpotifyArtistId(performance.artist.displayName).then(function (artistId) {
if (add == true) {
getTopTracks(artistId).then(function (trackstoAdd) {
tracks.push.apply(tracks, trackstoAdd);
cb();
});
} else {
//Other stuff... only looking at the true option at this point
}
});
}, function(err){
if( err ) {
console.log(err);
deferred.resolve(tracks);
} else {
deferred.resolve(tracks);
}
});
return deferred.promise;
}
問題は、cb() が then() 内にある場合、最終的なコールバックが呼び出されないことです。CB が promise コールバックの外に移動された場合、finalCallback が呼び出されますが、もちろん、呼び出されるのが早すぎます。
var AddToPlaylist = function (playlist, results) {
var allSongs = [];
var handler = function (performances, cb) {
getPerformances(playlist, performances, true)
.then(
function (trackstoAdd) { // all is well!
allSongs.push.apply(allSongs, trackstoAdd);
//console.log(allSongs) is as expected
cb();
}
,
function (err) { // something bad happened!
cb(err);
}
);
}
var finalCallback = function () {
console.log('test');
}
async.each(results, handler, finalCallback);
}