3

我正在制作一个小应用程序,显示艺术家相关艺术家的第一首歌曲列表。当我第一次尝试加载我的应用程序时,它什么也没显示。但是,当我“重新加载应用程序”时,一切似乎都正常。当我不断开始“重新加载”时,它也会不断向列表中添加更多相同的曲目。

如何阻止它不断向列表中添加更多曲目以及收紧代码以使其在加载时工作?

require([
  '$api/models',
  '$views/list#List',
  '$api/toplists#Toplist'

  ], function(models, List, Toplist){
    'use strict';

  // Build playlist
  function buildList(trackURIArray){
    var arr = trackURIArray;
    models.Playlist
      .createTemporary("myTempList")
      .done(function(playlist){ 
        playlist.load("tracks").done(function(loadedPlaylist){
          for(var i = 0; i < arr.length; i++){
            loadedPlaylist.tracks.add(models.Track.fromURI(arr[i]));
          }
        });

        // Create list
        var list = List.forPlaylist(playlist,{
          style:'rounded'
        });

        $('#playlistContainer').append(list.node);
        list.init();
      });
  }

  // Get top track
  function getTopTrack(artist, num, callback){
    var artistTopList = Toplist.forArtist(artist);

    artistTopList.tracks.snapshot(0, num).done(function (snapshot){ 
      snapshot.loadAll('name').done(function(tracks){
        var i, num_toptracks;
        num_toptracks = num; 

        for(i = 0; i < num_toptracks; i++){
          callback(artist, tracks[i]);
        }
      });
    });
  }

  // Get Related
  function getRelated(artist_uri){
    var artist_properties = ['name', 'popularity', 'related', 'uri'];

    models.Artist
    .fromURI(artist_uri)
    .load(artist_properties)
    .done(function (artist){

      artist.related.snapshot().done(function(snapshot){
        snapshot.loadAll('name').done(function(artists){
          var temp = [];

          for(var i = 0; i < artists.length; i++){

            getTopTrack(artists[i], 1, function(artist, toptrack){
              var p, n, u;

              p = artist.popularity;
              n = artist.name;
              u = artist.uri;

              temp.push(toptrack.uri);

            });
          }
          // Build a list of these tracks
          buildList(temp);
        });
      });
    });
  }

  getRelated('spotify:artist:2VAvhf61GgLYmC6C8anyX1');
});
4

2 回答 2

7

通过使用Promises,您可以延迟列表的呈现,直到您成功地将临时列表与您的曲目组合在一起。此外,为了防止在重新加载时添加重复的曲目,请为您的临时播放列表分配一个唯一的名称。

require([
  '$api/models',
  '$views/list#List',
  '$api/toplists#Toplist'
], function (models, List, Toplist) {
  'use strict';

  // Build playlist
  function buildList(trackURIArray) {
    var arr = trackURIArray;
    models.Playlist
      .createTemporary("myTempList_" + new Date().getTime())
      .done(function (playlist) {
        playlist.load("tracks").done(function () {
          playlist.tracks.add.apply(playlist.tracks, arr).done(function () {
            // Create list
            var list = List.forCollection(playlist, {
              style: 'rounded'
            });

            $('#playlistContainer').appendChild(list.node);
            list.init();
          });
        });
      });
  }

  // Get top track
  function getTopTrack(artist, num) {
    var promise = new models.Promise();
    var artistTopList = Toplist.forArtist(artist);

    artistTopList.tracks.snapshot(0, num).done(function (snapshot) {
      snapshot.loadAll().done(function (tracks) {
        promise.setDone(tracks[0]);
      }).fail(function (f) {
        promise.setFail(f);
      });
    });

    return promise;
  }

  // Get Related
  function getRelated(artist_uri) {
    models.Artist
      .fromURI(artist_uri)
      .load('related')
      .done(function (artist) {
        artist.related.snapshot().done(function (snapshot) {
          snapshot.loadAll().done(function (artists) {

            var promises = [];

            for (var i = 0; i < artists.length; i++) {
              var promise = getTopTrack(artists[i], 1);
              promises.push(promise);
            }

            models.Promise.join(promises)
              .done(function (tracks) {
                console.log('Loaded all tracks', tracks);
              })
              .fail(function (tracks) {
                console.error('Failed to load at least one track.', tracks);
              })
              .always(function (tracks) {
                // filter out results from failed promises
                buildList(tracks.filter(function(t) {
                  return t !== undefined;
                }));
              });
          });
        });
      });
  }

  getRelated('spotify:artist:2VAvhf61GgLYmC6C8anyX1');
});
于 2013-11-06T22:51:21.953 回答
2

我思考这样的事情的方式是想象我的连接速度非常慢。如果每个回调(完成,或传递给 getTopTrack 的函数)都需要 2 秒来响应,我需要如何构造我的代码来处理它?

这在这里如何应用?好吧,当你调用 buildList 时,temp 实际上是空的。我怀疑如果您首先在 getRelated 中创建播放列表,然后在 getTopTrack 的回调中向其中添加歌曲,那么它会起作用,因为列表会保持最新状态。

或者,您可以重新设计 getTopTrack 以返回一个 Promise,将所有顶级轨道 Promise 连接在一起(请参阅 each() 和 join() 上的 Promise 文档),然后在它们全部完成后构建列表。

至于为什么要获得多个列表,这是因为每次调用 buildList 时都会附加一个新列表。虽然当我将代码原样扔到我的操场区时,我没有看到这种行为。它只发生一次,当我重新加载应用程序时,它会从头开始。也许您有一个调用 getRelated 的重新加载按钮。

更新我一直在努力让它工作,但遇到了很多麻烦。每次添加后尝试调用 list.refresh 。现在尝试基于 Promise 的方法,但仍然无法让 List 显示任何内容。

于 2013-11-05T14:51:20.920 回答