node.js - 使用 passport-spotify 和 spotify-web-api-node 进行 API 调用的问题
问题描述
我有一个异步功能,它使用 Spotify 的授权来获取用户的顶级艺术家和曲目,然后将其放入数据库中。最近,我重组了我的数据库函数以支持异步调用,但现在我的 API 调用不再起作用。我收到一条错误消息,因为当代码到达该点时,我提供 api-call 的 accessKey 没有给出值,因此我推断问题是我的代码没有按需要播放异步性(尝试一个接一个地说这个词 10 次......)。
我对这种异步思考代码的方式非常陌生,并希望您能帮助我构建代码,以便它根据需要发挥作用。
目前,由于我上面描述的异步问题,代码在下一行停止,其中 accessToken 的值为“未定义”。
spotifyApi.setAccessToken(accessToken);
/* Function for retrieving data from spotify passport */
module.exports = function(passport) {
passport.use(
new SpotifyStrategy(
{
clientID: 'CLIENT ID',
clientSecret: 'CLIENT SECRET',
callbackURL: 'http://localhost:8888/auth/spotify/callback',
passReqToCallback: true
},
async (accessToken, refreshToken, expires_in, profile, done) => {
/* Put the incoming data in an object "aUser" */
const aUser = Object.create(user);
aUser.username = profile.username;
aUser.displayName = profile.displayName;
aUser.profilePicture = profile.photos[0];
aUser.email = profile._json.email;
/* RUN ALL CODE BELOW THIS IN userHandler Async function (to keep track of
user_id throughout all coming calls). This will first check if user
is in db, if not add it, and return it's user_id for coming calls, if
it is in db, it will simply return it's user_id to be used in coming
calls */
async function checking() {
/* Check if user is in DB, if not, add. Store user_id in "user" for
using in other calls */
let user_id = await checkUser(aUser.username, aUser.displayName, aUser.profilePicture, aUser.email);
/* Check if artistPreferences OR trackPreferences contain row that
was created 30 days or longer ago. If true, delete all rows
in both tables and then run code below. If false, return from function */
let preferencesStatus = await checkPreferences(user_id);
// If user preferences was older than 30 days and checkPreferences
// deleted the tables, run the folliwing code:
if (preferencesStatus === true) {
/* SET UP SPOTIFY API CALL TO GET TOP STATS FROM USER */
// Initialize spotifyapi object
var spotifyApi = new SpotifyWebApi();
// Set accesstoken for api objct
spotifyApi.setAccessToken(accessToken);
/* STEP 1: RETRIEVE TOP ARTISTS FOR CURRENT USER */
spotifyApi.getMyTopArtists({ limit: 1 })
.then(function(data) {
let topArtistsRaw = data.body.items;
// Map top artists and key data into a new array
let mappedArtists = topArtistsRaw.map(artist => {
return {
artist: artist.name,
popularity: artist.popularity,
url: artist.external_urls.spotify,
image: artist.images[0].url
}
});
// Map through each favorite artist of the user
mappedArtists.map(artist => {
let a_artist = artist.artist;
let a_popularity = artist.popularity;
let a_url = artist.url;
let a_image = artist.image;
// Check if artist is in the general artist-table, if not add
// Store the artist_id in variable
let artist_id = checkArtist(a_artist);
console.log(`artist ID NEW: ${artist_id}`);
// Add the artist to current users artistPreferences table
addArtistPreferences(user_id, artist_id);
});
});
/* STEP 2: RETRIEVE TOP TRACKS FOR CURRENT USER */
spotifyApi.getMyTopTracks({ limit:1 })
.then(function(data) {
let topTracksRaw = data.body.items;
// Map key data for each track into new array
let mappedTracks = topTracksRaw.map(track => {
return {
trackname: track.name,
artist: track.artists[0].name,
popularity: track.popularity,
url: track.external_urls.spotify
}
});
// Check if each track is in the DB, if not add
mappedTracks.map(track => {
let a_track = track.trackname;
let a_artist = track.artist;
let a_url = track.url;
let a_popularity = track.popularity;
// Check if current track is in the collective artist/track DB
// Store track_id in variable
let track_id = checkTrack(a_track, a_artist);
// Add the user trackPreferences DB's
addTrackPreferences(user_id, track_id, a_artist);
});
});
}
}
checking();
return done(null, profile);
}
)
);
// Serialize
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
}
解决方案
我必须做一些事情才能完成这项工作:
删除以下行:
passReqToCallback: true
- 激活此选项对 spotify 策略的响应类型错误,因此禁用它使其正确。我将映射函数调整为异步格式,如下所示:
mappedTracks.map(async track => { let a_track = track.trackname; let a_artist = track.artist; let a_url = track.url; let a_popularity = track.popularity; // Check if current track is in the collective artist/track DB // Store track_id in variable let track_id = await checkTrack(a_track, a_artist); console.log('user_id and track_id: ' + user_id + ' and ' + track_id); // Add the user trackPreferences DB's addTrackPreferences(user_id, track_id, a_artist); });
我还使用 await 语句更新了函数调用:
await checking();
推荐阅读
- javascript - 更改游戏而不更改之前添加的游戏
- python - 结合单空格和多空格分隔符读取平面文件
- javascript - 如何在 vue js 中使用方法函数在我的道具中给出千位分隔符
- android - 在 ic_launcher 中找不到资源
- python-3.x - 如何存储 pandas 时间序列并应用复杂的 groupby
- excel - Excel Array公式计算移动平均异常值
- r - 将 2 个箱线图合并为 1 个
- date - 无效的日期常数:尝试将数据子集到日期范围内
- rtsp - 如何从公共 Earthcam 视频中获取 RTSP URL
- c - 当在 C 中声明为本地或全局时,const 存储在内存布局中的位置