首页 > 解决方案 > Spotify API,无法正确链接两个 API 调用

问题描述

我无法链接这两个 API 调用。所以基本上我正在尝试重新创建 Spotify 界面,并且单独地,这些调用实际上工作得很好!

我还有一个“onPlayClick”函数,它与“onNextClick”基本相同,如下所示,但端点不同,并且是 PUT 方法而不是 POST 方法。正确播放并设置 selectedSong 的状态。

但是,调用 updateCurrentlyPlaying 的 onNextClick 无法按预期工作。预期的功能是,当用户单击下一步时,歌曲将转到下一个曲目(有效!),然后更新 UI 上的曲目信息。

但最终发生的是它首先更新轨道信息然后切换轨道,所以在 UI 上它在某种意义上总是“落后一个轨道”,我不知道为什么第二个 API 领先于第一个!:S 非常感谢任何帮助!

onNextClick = () => {
  const { deviceId, token } = this.state
  fetch(`https://api.spotify.com/v1/me/player/next?device_id=${deviceId}`, {
    method: 'POST',
    headers: { 'Authorization': 'Bearer ' + token },
  })
  .then(response => response.json())
  .then(this.updateCurrentlyPlaying())  
 }



updateCurrentlyPlaying(){
    const { deviceId, token } = this.state;

    let selectedSong;
    fetch(`https://api.spotify.com/v1/me/player/currently-playing?device_id=${deviceId}`, {
      method: 'GET',
      headers: { 'Authorization': 'Bearer ' + token },
    })
    .then(response => response.json())
    .then(data => {
      selectedSong = {
        name: data.item.name,
        duration: Math.round(data.item.duration_ms / 1000),
        artists: data.item.artists,
        album: data.item.album.name,
        image: data.item.album.images[0],
        id: data.item.id,
        uri: data.item.uri,
        offset: data.offset
      }
      this.setState({ selectedSong })
    })
  }

标签: javascriptreactjsspotifyes6-promisefetch-api

解决方案


更新的答案

如下所述,下面的原始答案可能仍然相关。然而,第一个问题this.updateCurrentlyPlaying是调用方式。在写作.then(this.updateCurrentlyPlaying())中,您立即调用this.updateCurrentlyPlaying,它正在传递undefined回 Promise 链。

相反,你想要这样的东西:

onNextClick = () => {
  const { deviceId, token } = this.state
  fetch(`https://api.spotify.com/v1/me/player/next?device_id=${deviceId}`, {
    method: 'POST',
    headers: { 'Authorization': 'Bearer ' + token },
  })
  .then(() => this.updateCurrentlyPlaying()) 
 }

原始答案

我的猜测是您的代码很好,但 Spotify 的行为与您期望的不同。当您 POST 到me/player/next时,端点会立即响应代码 204,表明它已收到您的请求。

事实上,这就是Spotify API 文档所说的:

完成的请求将返回 204 NO CONTENT 响应代码,然后向播放器发出命令。

这意味着您的代码看到 204 并立即继续为当前曲目调用 Spotify API。这发生在Spotify 的播放器调用上述传递之前。command to the player

我对 Spotify API 不是很熟悉,而且我看到这是 Beta 版——也许他们会在不久的将来提供更优雅的解决方案。在那之前,您最好的选择可能是重试第二次呼叫(有超时限制)几次,直到您确认轨道确实发生了变化。

这是一个快速示例,您可以如何实现它:

  updateCurrentlyPlaying(priorSongId) {
    const {deviceId, token} = this.state;

    let selectedSong;
    let numTries = 0;
    const retryFetchUntilUpdate = () => {
      fetch(`https://api.spotify.com/v1/me/player/currently-playing?device_id=${deviceId}`, {
        method: 'GET',
        headers: {'Authorization': 'Bearer ' + token},
      })
        .then(response => response.json())
        .then(data => {
          if (data.item.id === priorSongId && numTries < 5) {
            numTries += 1;
            setTimeout(retryFetchUntilUpdate, 250)
          } else {
            selectedSong = {
              name: data.item.name,
              duration: Math.round(data.item.duration_ms / 1000),
              artists: data.item.artists,
              album: data.item.album.name,
              image: data.item.album.images[0],
              id: data.item.id,
              uri: data.item.uri,
              offset: data.offset
            }
            this.setState({selectedSong})
          }
        })
    }
    retryFetchUntilUpdate();
  }


推荐阅读