async函数中await未等待,Express调用Spotify API无法正常获取返回值
问题原因
你只等待了setUpSpotifyApi的执行完成,没有等待它回调内部的spotifyApi.getPlaylist这个异步请求完成。外层await仅监听了setUpSpotifyApi的Promise状态,内部嵌套的getPlaylist异步请求没有被外层捕获,因此代码走到await setUpSpotifyApi(...)结束后,getPlaylist还在后台运行,此时trackList仍为初始的null值,函数就已经执行返回了。等后续getPlaylist请求完成给trackList赋值时,函数已经结束运行,赋值操作不会影响已经返回的结果。
修正方案
尽量避免在async/await逻辑中嵌套.then回调,统一用await处理所有异步操作,逻辑更清晰也不会遗漏异步等待:
修正getOldTracks函数
const getOldTracks = async (playlistId, userName) => { try { // 等待获取spotifyApi实例 const spotifyApi = await setUpSpotifyApi(userName) // 新增await,等待getPlaylist请求完成再往下执行 const data = await spotifyApi.getPlaylist(playlistId) console.log('in spotify api call', data.body.tracks.items) return data.body.tracks.items } catch (err) { console.log("请求过程出错", err) // 可根据业务需求返回空数组,或者抛出错误交给上层处理 return [] } };
优化路由代码
不要同时混用await和.then,两种异步写法选一种即可,同时注意要给前端返回响应,避免请求挂起:
router.post("/remix", async (req, res) => { try { // 获取歌曲信息 const oldTracks = await getOldTracks(req.body.playlistId, req.user.username) console.log('returned to original call', oldTracks) res.json({ tracks: oldTracks }) } catch (err) { console.log('this is an error', err) res.status(500).json({ error: '获取播放列表失败' }) } });
原控制台输出顺序说明
await setUpSpotifyApi执行完成,进入回调触发spotifyApi.getPlaylist,该请求是异步非阻塞的,外层await直接结束- 打印
after await null,函数返回null给上层路由 - 路由拿到返回的null,打印
returned to original call null - 后台
getPlaylist请求完成,执行内部回调打印in spotify api call [],但此时函数早已返回,赋值无效
内容的提问来源于stack exchange,提问作者Brian Boylen
相关产品推荐
相关产品推荐

