Подтвердить что ты не робот

Как выбрать прослушиватель событий, который позволит мне дождаться завершения async.times для запуска функции

Я использую node.js-сервер, Spotify API и spotify-web-api-js node модуль для создания веб-приложение, в котором пользователь может ввести имя исполнителя, посмотреть список песен от смежных исполнителей, а затем дополнительно сохранить этот плейлист в свою собственную учетную запись 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 полного кода здесь, хотя это может не сработать, потому что я использую браузер на моем собственном сервере)

Прямо сейчас, в строке 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 уже загружен, прежде чем я получу эти данные. Я рассмотрел этот вопрос, но это не помогло мне решить эту проблему. Спасибо!

EDIT: Теперь у меня есть массив 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 {}

В принципе, он не получает параметр по какой-то причине. И я запишу playlist_id заранее, поэтому могу сказать, что он работает (также я вижу пустые плейлисты с указанным заголовком, созданным в моей учетной записи Spotify).

Полный обновленный код здесь: https://github.com/yamilethmedina/cs50xmiami/blob/master/assignments/portfolio/public/scripts.js

4b9b3361

Ответ 1

Аргумент обратного вызова async.times может принимать второй аргумент "results", поэтому, если вы вызываете "next" с помощью 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);
        });

    });

}