我遍历一个数组并调用函数'getTopTracks',它生成一个json请求(使用LastFM包装器插件https://github.com/fxb/javascript-last.fm-api)。然后我将该信息存储在一个新的数组“tracks_all”中。
在使用“tracks_all”数组执行操作之前,如何等待每个API调用的结果完成?
// array of last.fm usernames
var user_list = ['user1', 'user2','etc'];
// get top tracks
var getTopTracks = function( user, callback ){
var last_fm;
last_fm = new LastFM({
apiKey : //apikey,
apiSecret : //apiSecret
});
// method of last.fm api
last_fm.user.getTopTracks({
user : user,
period : //period,
limit : //num of tracks
}, {
success: function( data ){
var track_arr;
track_arr = data.toptracks.track;
callback( track_arr );
},
error: function( code, message ){}
});
};
var newFetch = function(){
var user_list_len,
i,
tracks_all = [];
user_list_len = user_list.length;
for( i = 0; i < user_list_len; i++ ){
getTopTracks(
user_list[ i ],
function( data ){
var track_data = data;
// combine into one big array
tracks_all.push.apply( tracks_all, track_data );
});
}
};
// What I want to do is something like...
var get_tracks = newFetch();
// if the loop is done and all results are in
// call the function outputToDom()
答案 0 :(得分:2)
这是使用Promise
when
样式
// array of last.fm usernames
var user_list = ['user1', 'user2','etc'];
// get top tracks
var getTopTracks = function( user ){
var last_fm;
var deferred = when.defer();
last_fm = new LastFM({
apiKey : //apikey,
apiSecret : //apiSecret
});
// method of last.fm api
last_fm.user.getTopTracks({
user : user,
period : //period,
limit : //num of tracks
}, {
success: function( data ){
var track_arr;
track_arr = data.toptracks.track;
deferred.resolve(track_arr);
},
error: function( code, message ){
deferred.reject(code);
}
});
return deferred.promise();
};
var newFetch = function(){
var deferred = when.defer();
var promises = [];
user_list.forEach(function(user){
promises.push(getTopTracks(user));
});
when.all(promises, function(results){
// results will be an array of track_arr
deferred.resolve(results);
}, function(error){
deferred.reject(error);
});
return deferred.promise;
};
// What I want to do is something like...
var get_tracks = newFetch();
get_tracks.done(function(results){
// results will be an array of track_arr
}, function(error){
// handle error
});
这是使用Callback
async
样式
// array of last.fm usernames
var user_list = ['user1', 'user2','etc'];
// get top tracks
var getTopTracks = function( user, callback ){
var last_fm;
var deferred = when.defer();
last_fm = new LastFM({
apiKey : //apikey,
apiSecret : //apiSecret
});
// method of last.fm api
last_fm.user.getTopTracks({
user : user,
period : //period,
limit : //num of tracks
}, {
success: function( data ){
var track_arr;
track_arr = data.toptracks.track;
callback(null, track_arr)
},
error: function( code, message ){
callback(code);
}
});
};
var newFetch = function(callback){
var functions = [];
user_list.forEach(function(user){
functions.push(getTopTracks(user));
});
async.parallel(functions, callback);
};
// What I want to do is something like...
newFetch(function(error, results){
// results will be an array of track_arr
});
更新语法
答案 1 :(得分:0)
由于您知道函数getTopTracks
将被执行多少次,因此您可以使用计数器来跟踪剩余执行getTopTracks
的次数。
在newFetch()
:
var newFetch = function () {
var user_list_len,
i,
tracks_all = [];
user_list_len = user_list.length;
var cpt = user_list.length; // N executions left
for (i = 0; i < user_list_len; i++) {
getTopTracks(
user_list[i],
function (data) {
var track_data = data;
// combine into one big array
tracks_all.push.apply(tracks_all, track_data);
--cpt; // One execution has finished
if (cpt === 0) { // 0 execution left
outputToDom(); // -> Call the final callback
}
});
}
};