【问题标题】:How to pick an event listener that will let me wait until async.times is finished to run a function如何选择一个事件监听器,让我等到 async.times 完成运行函数
【发布时间】:2016-01-30 00:55:38
【问题描述】:

我正在使用 node.js 服务器、Spotify API 和 spotify-web-api-js 节点模块来创建一个 Web 应用程序,用户可以在其中输入艺术家的姓名,查看相关艺术家的歌曲列表,然后可以选择将该播放列表保存到他们自己的 Spotify 帐户。但是,我仍然无法完成最后一步。

我的用户授权流程首先发生:

if (params.access_token) {

    s.setAccessToken(params.access_token);

    s.getMe().then(function(data) {

      console.log(data);
      console.log(data.id);
      user_id = data.id;

下面是 API 收集歌曲实际细节的地方。虽然它在较低的位置,但它首先发生,并且只有在用户单击该页面上的第二个按钮时才会发生用户授权。

async.times(counter, function(n, next){
        s.getArtistTopTracks(relatedArtists[n].id, "US", function (err, data2) {
          relatedArtists[n].song = data2.tracks[0].name;
          relatedArtists[n].uri = data2.tracks[0].uri;
          console.log(relatedArtists[n].uri);
          // make sure to put the access token here add song to playlist
          // create array
          song_uris.push(relatedArtists[n].uri);
          console.log(song_uris);

          // song_uris = relatedArtists[n].uri;
          //
          // console.log(song_uris);

          next(null);

      $("#playlist").load(function() {
            s.addTracksToPlaylist(user_id, playlist_id, song_uris);
          });
        });


      }, function(err) {
        // console.table(relatedArtists);

        for (k = 0; k < 20; k++)
        {
          $('#related-artist').append('<p><strong>' + relatedArtists[k].name + '</strong> -- \"' + relatedArtists[k].song + '\"</p>');


        }

JSBin of full code here,虽然它可能不起作用,因为我在自己的服务器上使用 browserify)

现在,在第 114 行,我有 song_uris.push(relatedArtists[n].uri); 使用 async.times 将内容推送到一个数组中。由于这是我在第 66 行创建播放列表的位置,它显示为一个空数组:

 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(song_uris);


       });

那里,console.log(song_uris) 显示一个空数组,所以 addTracksToPlaylist() 像这样中断:

另一方面,如果我尝试在下面addTracksToPlaylist(),我没有访问用户帐户的授权。

在显示歌曲列表的基本功能已经运行之后,稍后添加了用户授权流程,但我不确定如何有效地重构它以将该列表保存到我的用户的播放列表中。目前,我只是在 Spotify 帐户中创建一个空的播放列表。

我可以添加什么样的事件监听器,让它等到async.times 的每个实例都被执行,这样addTracksToPlaylist() 才能工作?在我获得这些数据之前,DOM 已经初始加载。我查看了this question,但它并没有完全帮助我解决这个问题。谢谢!

编辑:我现在已经按照我需要的方式创建了 song_uri 数组,但我仍然无法将它放入播放列表。我一直在玩弄我的访问令牌的位置,以便我可以访问创建的播放列表,但仍然没有运气。

第 130 行的 console.log(song_uris); 语句显示了我需要的完整数组,但是当我将其插入 s.addTracksToPlaylist(user_id, playlist_id, song_uris); 时,我在开发者控制台中收到以下错误:

POST https://api.spotify.com/v1/users/tenderoni-/playlists/7MtQTzUsxD4IEJ8NmmE36q/tracks?uris= 400 (Bad Request)
bundle.js:10616
Uncaught (in promise) XMLHttpRequest {}

基本上,由于某种原因,它没有接收到参数。我事先记录了playlist_id,所以我可以知道它正在工作(另外,我看到在我的 Spotify 帐户中创建了具有指定标题的空白播放列表)。

完整更新代码在这里:https://github.com/yamilethmedina/cs50xmiami/blob/master/assignments/portfolio/public/scripts.js

【问题讨论】:

  • 您是否打算在 JSBin 帖子中包含凭据?我不知道这些是来自某个 API 文档还是你的。

标签: javascript jquery asynchronous spotify addeventlistener


【解决方案1】:

async.times 的回调参数可以接受第二个“结果”参数,因此如果您使用 song_uri 调用“下一个”,您可以绕过循环的每一轮,最后可以得到 song_uris,通过回调传递searchArtists,并在那里使用它。骨架版:

$(document).ready(function($) {
    $('#s').on('submit', function() {
        searchArtists($('#originalartist').val(), function(err, song_uris) {
            if (params.access_token) {
                // omitted
                s.setAccessToken(params.access_token);
                s.getMe().then(function(data) {
                    console.log(data);
                    console.log(song_uris);
                });
            }
        });
        return false;
    });
})

function searchArtists(originalArtist, callback) {
    s.getArtistRelatedArtists(originalArtistId, function(err, data) {
        async.times(counter, function(n, next) {
            // omitted
            next(related_artists[n].uri)
        }, function(err, song_uris) {
            callback(err, song_uris);
        });

    });

}

【讨论】:

  • s.createPlaylist() 是否会进入第一部分,在 getMe() 函数中?
  • 是的,因为您仍然需要 getMe() 回调中的 user_id 才能调用 s.createPlaylist()。由于 getMe() 已经在 searchArtists 的回调中,因此您也可以访问 song_uris。
  • 我注意到它从 getArtistRelatedArtists() 跳转到 async.times()。 getArtistTopTracks() 不应该介于这两行之间吗?我通过该功能从每个相关艺术家那里获得第一首歌,以填充 song_uris。我想我应该回到我的初始代码然后尝试再次实现它,因为我认为我可能已经搞砸了其他东西来打破在屏幕上打印播放列表的 for 循环,歌曲在浏览器中显示为未定义但不是控制台, & 当我看到 account.spotify.com 的流量时,我不再收到控制台响应。
  • 谢谢,该功能已恢复,但似乎没有任何东西推送到 song_uris 数组。当我按下按钮时,我的终端显示我正在登录我的 spotify 帐户,但它没有在我的最终函数回调中运行我的 console.log(song_uris)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-14
  • 1970-01-01
  • 1970-01-01
  • 2016-09-20
相关资源
最近更新 更多