【问题标题】:Saved (globally defined) array is emptied after callback回调后清空保存的(全局定义的)数组
【发布时间】:2016-05-08 11:39:54
【问题描述】:

我正在使用spotify-web-api-js 节点模块、JavaScript 和 jQuery 登录用户的 Spotify 帐户并将一组曲目保存到新创建的播放列表中,但到目前为止我只能创建一个空白播放列表。

我通过 API 收集所有曲目,并在向用户显示列表时将它们放入全局定义的数组中。该数组在第 39 行定义:var song_uris = []; console.log 表明这个数组在这个函数之后填充了我需要的 URI,这发生在初始搜索时:

function searchArtists(originalArtist, callback) {
    $(window).on('hashchange', function() {
      console.log(window.location.hash);
    });
  console.log('originalArtist', originalArtist);
  $.getJSON("https://api.spotify.com/v1/search?type=artist&q=" + originalArtist, function(json) {

    $('#artist').html('<p>'+ '<img src="' + json.artists.items[0].images[2].url + '" height="100" width="100" /> ' + json.artists.items[0].name +'</p>');

    var originalArtistId = json.artists.items[0].id;
    s.getArtistRelatedArtists(originalArtistId, function(err, data) {
      relatedArtists = {};

      for (var i = 0; i < data.artists.length; i++) {
        relatedArtists[data.artists[i].id] = {};
        relatedArtists[data.artists[i].id].name = data.artists[i].name;
        relatedArtists[data.artists[i].id].id = data.artists[i].id;
      }



      var counter = 0;
      for (var id in relatedArtists) {
        relatedArtists[counter] = relatedArtists[id];
        delete relatedArtists[id];
        counter++;
      }

        async.times(counter, function(n, next) {
          console.log(n);
          console.log(relatedArtists[n].id);
          s.getArtistTopTracks(relatedArtists[n].id, "US", function (err, data2) {
            relatedArtists[n].song = data2.tracks[0].name; //sometimes this is a TypeError? idk
            relatedArtists[n].uri = data2.tracks[0].uri;

            $('#related-artist').append('<p><strong>' + relatedArtists[n].name + '</strong> -- \"' + relatedArtists[n].song + '\"</p>');
            song_uris.push(relatedArtists[n].uri);

            next(null, relatedArtists[n].uri);

          });

        }, function(err, song_uris) {


          console.log(song_uris); //array is full here

     });

   });
 });
}

但是,一旦人们通过可选的登录/回调过程,我就会获得所有用户的数据(包括新的播放列表 URI),但我之前拥有的 song_uris 数组现在是空的。

if (params.access_token) {

          s.setAccessToken(params.access_token);
          s.getMe().then(function(data) {

            // and here it goes the user's data!!!
            console.log(data);
            console.log(data.id);
            user_id = data.id;

            s.createPlaylist(user_id, {name: 'Related Artist Playlist'}).then(function(data3) {
              console.log(data3);
              playlist_id = data3.uri;
              playlist_id = playlist_id.substring(33);
              console.log(playlist_id);
              console.log(user_id);
              console.log(song_uris); //array is empty here





              s.addTracksToPlaylist(user_id, playlist_id, song_uris).then(function(data){
                  console.log(data);
                });

        });
      });
    }

由于这是addTracksToPlaylist 函数的参数之一,XML 请求不起作用。

这是我的控制台的屏幕截图,其中我看到一个失败的 POST 请求和一个 uncaught exception: object XMLHttpRequest

范围和/或异步显然存在问题,但我似乎无法弄清楚将addTracksToPlaylist 放在哪里。将它放在 console.log 输出完整数组的行之后,要么不执行任何操作(如果它在 window.onhashchange = function () 内),要么给出错误,因为在回调之前未定义用户和播放列表(如果 addTracksToPlaylist功能是单独存在的)。

网站刷新回调后数据是否被覆盖?如果是这样,我该如何阻止它,以便我拥有适合 URL 字符串的完整 URI 数组? (根据Spotify Developer docs,URL 应该通过uri 参数将轨道URI 的逗号分隔列表(在我的数组中)传递给它,但是由于空数组它会中断并且我得到@987654338 @(使用空参数)。我该如何解决这个问题?或者是否有另一种方法来保持搜索艺术家所需的用户流 -> 查看相关艺术家的歌曲列表 -> (可选)登录到 Spotify 帐户 -> (可选)将相关艺术家的歌曲列表保存到新播放列表?

我还用完整的 JS 和 HTML 代码创建了一个 jsfiddle:https://jsfiddle.net/37Lkrcb1/1/

注意:这是在 Node.js 服务器上运行的,我使用 bundle 和 browserify 来编译脚本。

【问题讨论】:

  • 听起来页面在登录/回调操作期间正在刷新。
  • 这是有道理的。 event.preventDefault();在那种情况下可能有用吗?
  • 这完全取决于为什么要刷新。
  • @T.J.Crowder 当新用户点击登录时,他们会被踢到 Spotify 的授权页面;这显然可以解释这种情况下的刷新。但是,即使我已经登录到 Spotify 网络界面,页面仍然会刷新,因此永远不会看到该屏幕。

标签: javascript jquery arrays asynchronous spotify


【解决方案1】:

听起来您的应用中至少有一条路径会涉及您无法避免的页面刷新(转到 Spotify 并返回)。在这种情况下,您的所有变量都将在页面加载时重置。

如果您有 song_uris 并希望在重新加载过程中保持不变,您可以在 Spotify 身份验证之前将它们存储在 sessionStorage(或 localStorage)中,并在页面加载时检索它们。

存储它:

sessionStorage.setItem("song_uris", JSON.stringify(song_uris));
// Or localStorage.setItem...

在页面加载时检索它:

var song_uris = JSON.parse(sessionStorage.getItem("song_uris") || "null");
if (!song_uris) {
    // There weren't any in storage, populate in another way or set dfeault
}

Web storagenearly universally supported

【讨论】:

  • 这正是我所需要的!我将更多地研究网络存储,因为它在各种情况下都非常有用。接受,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多