如何选择一个事件监听器,让我等到async.times完成后才能运行一个函数

Yam*_*ina 13 javascript jquery asynchronous addeventlistener spotify

我正在使用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;
Run Code Online (Sandbox Code Playgroud)

下面是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>');


        }
Run Code Online (Sandbox Code Playgroud)

(这里是完整代码的JSBin,虽然它可能不起作用,因为我在自己的服务器上使用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);


       });
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

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

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

我可以添加什么样的事件监听器,以便它会等到每个单个实例async.times都执行,这样addTracksToPlaylist()才能工作?在获取此数据之前,DOM已初始加载.我看了这个问题,但它并没有帮我解决这个问题.谢谢!

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

console.log(song_uris);130行的语句显示了我需要的已完成的数组,但是当我插入它时,我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 {}
Run Code Online (Sandbox Code Playgroud)

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

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

小智 2

async.times 的回调参数可以采用第二个“results”参数,因此,如果您使用在循环的每一轮中获得的 Song_uri 调用“next”,则可以在最后获取 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);
        });

    });

}
Run Code Online (Sandbox Code Playgroud)