You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spotify API接口多用户并发调用时艺术家数据混乱问题

问题原因与解决方案

核心问题

你猜对了,问题确实出在artists_names的声明方式上。这段代码里artists_names = []没有用var/let/const声明,导致它变成了全局变量。Node.js的全局变量是所有请求共享的,当两个用户同时调用接口时:

  1. 请求A先执行artists_names = []并填充自己的艺术家信息
  2. 还没等请求A的youtube.search回调执行,请求B就覆盖了artists_names为新数组并填充自己的艺术家信息
  3. 当两个请求的youtube.search回调先后执行时,都会读取最后被修改的那个artists_names,就出现了串数据的情况

其他返回值(比如track_name、album_cover)正常,是因为它们直接从data.body.item中读取,而data是每个请求回调的局部变量,不会被其他请求干扰。

修复方案

给artists_names加上const(或者let),把它变成当前回调作用域的局部变量,每个请求都会创建独立的数组:

app.post("/get-spotify-data", async (req, res) => {
  var spotifyApi = new SpotifyWebApi();

  spotifyApi.setAccessToken(req.body.accessToken);

  await spotifyApi.getMyCurrentPlayingTrack().then(
    function (data) {
      if (data.body.item) {
        // 加上const,变成局部变量
        const artists_names = [];

        data.body.item.artists.forEach((artist) => {
          artists_names.push(artist.name);
        });

        youtube
          .search(data.body.item.name + data.body.item.artists[0].name)
          .then((results) => {
            res.json({
              track_name: data.body.item.name,
              album_cover: data.body.item.album.images[0].url,
              artists: artists_names.join(","),
              link: results.videos[0].link,
            });
          });
      }
    },
    function (err) {
      console.log("Something went wrong!", err);
    }
  );
});

额外优化建议

你这段代码混合使用了await和.then(),写法不够统一,容易造成嵌套混乱。可以改成全async/await的风格,可读性更好:

app.post("/get-spotify-data", async (req, res) => {
  try {
    const spotifyApi = new SpotifyWebApi();
    spotifyApi.setAccessToken(req.body.accessToken);

    const data = await spotifyApi.getMyCurrentPlayingTrack();
    if (!data.body.item) {
      // 处理无播放歌曲的情况
      return res.status(200).json({});
    }

    const artists_names = data.body.item.artists.map(artist => artist.name);
    const results = await youtube.search(`${data.body.item.name} ${data.body.item.artists[0].name}`);

    res.json({
      track_name: data.body.item.name,
      album_cover: data.body.item.album.images[0].url,
      artists: artists_names.join(","),
      link: results.videos[0].link,
    });
  } catch (err) {
    console.log("Something went wrong!", err);
    // 给前端返回错误响应,避免请求挂起
    res.status(500).json({ error: err.message });
  }
});

这里用map代替forEach生成艺术家名字数组,代码更简洁;同时用try/catch统一处理所有异步错误,补充了无播放歌曲和错误响应的处理,避免前端请求一直处于等待状态。

内容的提问来源于stack exchange,提问作者Broump

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 05:25:28