等待所有循环结果Javascript

时间:2013-11-22 00:07:59

标签: javascript jquery last.fm

我遍历一个数组并调用函数'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()

2 个答案:

答案 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
        }
      });
  }
};