在youtube搜索api函数之外的变量undefined

时间:2017-11-24 16:01:34

标签: javascript node.js youtube youtube-api async-await

我从youtube api获取播放列表。

在youtube搜索功能中输出控制台时,它会提供正确的输出。

它提供了未定义的youtube搜索api函数。

 var playlistId;
async function suggestTrack(genre) {

    youtube.search.list({
      auth: config.youtube.key,
      part: 'id,snippet',
      q: genre
    }, function (err, data) {
      if (err) {
        console.error('Error: ' + err);
      }
      if (data) {
        console.log(data.items[0].id.playlistId); //getting the id
        playlistId = data.items[0].id.playlistId;

      }
      //process.exit();
    });

    console.log(playlistId);// undefined

const tracks = await youtube_api.getPlaylistTracks(playlistId);
return tracks[Math.floor(tracks.length * Math.random())];

}

2 个答案:

答案 0 :(得分:3)

API调用是异步的。并且在api的响应甚至回来之前,您正在打印playlistId的值。你必须等待回应。由于您使用asyncPromise中打包api调用并使用await。要宣传search.list方法,您有很多选择,或者您可以自己完成,如下所示

function search(key, part, genre) {
  return new Promise((resolve, reject) => {
    youtube.search.list({
      auth: key,
      part: part,
      q: genre
    }, function (err, data) {
      if (err) {
        reject(err);
        return;
      }
      // use better check for playlistId here
      resolve(data ? data.items[0].id.playlistId : null);
    })
  });
}

// then use it here
async function suggestTrack(genre) {
  const playlistId = await search(config.youtube.key, 'id,snippet', genre);      
  const tracks = await youtube_api.getPlaylistTracks(playlistId);
  return tracks[Math.floor(tracks.length * Math.random())];
}

答案 1 :(得分:2)

youtube.search.list是异步的。您正尝试访问playlistId,因为它是同步过程的一部分。

您可以将youtube.search.list打包到Promise内以简化其使用。

OLD WAY

function wrappedSearch() {
  return new Promise((resolve, reject) => {
    youtube.search.list({
      auth: config.youtube.key,
      part: 'id,snippet',
      q: genre
    }, (err, data) => {
      if (err) {
        console.error('Error: ' + err);

        return reject(err);
      }

      return resolve((data && data.items[0].id.playlistId) || false);
    });
  });
}

async function suggestTrack(genre) {
  const playlistId = await wrappedSearch();

  // Here playlistId is either the playlistId, either false

  console.log(playlistId);

  const tracks = await youtube_api.getPlaylistTracks(playlistId);

  return tracks[Math.floor(tracks.length * Math.random())];
}

新方式

在节点v8 doc中可用  tutorial

const {
   promisify,
} = require('util');

const youtubeSearchAsync = promisify(youtube.search.list);

async function suggestTrack(genre) {
  const data = await youtubeSearchAsync({
      auth: config.youtube.key,
      part: 'id,snippet',
      q: genre
  });

  const playlistId = (data && data.items[0].id.playlistId) || false;

  console.log(playlistId);

  const tracks = await youtube_api.getPlaylistTracks(playlistId);

  return tracks[Math.floor(tracks.length * Math.random())];
}