node.js порядок вызова функций, веб-API Spotify

#javascript #node.js #spotify-app

#javascript #node.js #spotify-приложение

Вопрос:

Я пытаюсь использовать веб-API Spotify с оболочкой для node.js . Прежде чем я выполню какой-либо из вызовов API, мне нужно установить токен доступа. В моем скрипте я setAccessToken сначала вызываю функцию, а затем вызываю некоторый запрос API ниже. Однако из-за асинхронного характера node.js мой setAccessToken метод вызывается после моих запросов API, что приводит к неудачным запросам API. Как я могу убедиться, что моя setAccessToken функция возвращается, прежде чем вызывать запросы API ниже (строки запроса API начинаются с spotifyApi.getMySavedTracks call)

 app.get('/callback', (req, res) => {
  var code = req.query.code || null;
  if (code === null) {
      console.log("code is null");
  }

  async function authorize() {
    const data = await spotifyApi.authorizationCodeGrant(code);
    // console.log('The token expires in '   data.body['expires_in']);
    // console.log('The access token is '   data.body['access_token']);
    // console.log('The refresh token is '   data.body['refresh_token']);
    // Set the access token on the API object to use it in later calls
    accesToken = data.body['access_token'];
    refreshToken = data.body['refresh_token'];
    spotifyApi.setAccessToken(accesToken);
    spotifyApi.setRefreshToken(refreshToken);
  }

  try {
    authorize();
  } catch (err) {
    console.log('Something went wrong!', err);
  }

  spotifyApi.getMySavedTracks({
    limit : lim,
    offset: 1
  })
  .then(function(data) {
    return data.body.items;
  }, function(err) {
    console.log('Something went wrong!', err);
  })
  .then(function(items) {
    let ids = [];
    items.forEach(function(item) {
      ids.push(item.track.id);
    })
    return spotifyApi.getAudioFeaturesForTracks(ids); //2xc8WSkjAp4xRGV6I1Aktb
  })
  .then(function(data) {
    let songs = data.body.audio_features;
    //console.log(songs);
    let filteredSongURIs = [];
    songs.forEach(function(song) {
      if ((song.energy >= moodScore-offset) amp;amp; (song.energy <= moodScore offset)) {
        filteredSongURIs.push(song.uri);
      }
    })

    //Create Playlist with filtered songs
    spotifyApi.createPlaylist('Mooder Playlist', { 'description': 'My description', 'public': true })
    .then(function(data) {
      return data.body.id;
    }, function(err) {
      console.log('Something went wrong!', err);
    })
    .then(function(playlist) {
      spotifyApi.addTracksToPlaylist(playlist, filteredSongURIs)
    })
    .then(function(data) {
      console.log('Added tracks to playlist!');
    }, function(err) {
      console.log('Something went wrong!', err);
    });
    
  }, function(err) {
    console.log(err);
  });


  res.redirect('/testAPI');
});
 

Ответ №1:

Вы можете перенести весь свой код после setAccessToken в другой then , или вы можете await это Promise закончить:

 // Add `async` here
app.get('/callback', async (req, res) => {
  var code = req.query.code || null;
  if (code === null) {
      console.log("code is null");
  }
  try {
    const data = await spotifyApi.authorizationCodeGrant(code);
    // console.log('The token expires in '   data.body['expires_in']);
    // console.log('The access token is '   data.body['access_token']);
    // console.log('The refresh token is '   data.body['refresh_token']);
    // Set the access token on the API object to use it in later calls
    accesToken = data.body['access_token'];
    refreshToken = data.body['refresh_token'];
    spotifyApi.setAccessToken(accesToken);
    spotifyApi.setRefreshToken(refreshToken);
  } catch (err) {
    console.log('Something went wrong!', err);
  }

  // The rest of your code
 

Комментарии:

1. оказывается spotifyApi.authorizationCodeGrant , это не асинхронная функция. Потому что я получил «Синтаксическая ошибка: ожидание допустимо только в асинхронной функции» @emi

2. Проблема не в spotifyApi.authorizationCodeGrant том, что вызывающая его функция должна быть объявлена как async , чтобы ее можно было использовать await .

3. Я поместил весь код внутри блока try в асинхронную функцию и вызвал ее в try. Однако я получаю ту же проблему

4. @Khashhogi Извините, я не могу понять этот последний комментарий.

5. Соответствующим образом обновите свой вопрос