简体   繁体   English

Spotify API,无法正确链接两个API调用

[英]Spotify API, can't chain two API calls properly

I'm having trouble chaining these two API calls. 我在链接这两个API调用时遇到麻烦。 So basically I'm trying to recreate the Spotify interface and individually, these calls actually work which is great! 因此,基本上,我试图重新创建Spotify接口,并且这些调用实际上可以正常工作,这很棒!

I also have an 'onPlayClick' function that's basically the same function as 'onNextClick' as seen below, but with a different endpoint and is a PUT method instead of a POST method. 我还具有一个“ onPlayClick”功能,该功能与“ onNextClick”基本上相同,如下所示,但是具有不同的端点,并且是一种PUT方法而不是POST方法。 That plays and sets the state of selectedSong correctly. 正确播放并设置selectedSong的状态。

However, onNextClick calling updateCurrentlyPlaying does not work as intended. 但是,onNextClick调用updateCurrentlyPlaying无法正常工作。 The intended functionality is that when the user clicks next, the song would go to the next track (which works!), AND THEN updates the track information on the UI. 预期的功能是,当用户单击下一步时,歌曲将转到下一个曲目(有效!),然后在UI上更新曲目信息。

But what ends up happening is that it FIRST updates the track information AND THEN switches track, so on the UI it's always "one track behind" in a sense and I do not know why the second API is getting ahead of the first one! 但是最终发生的事情是它首先更新了轨道信息,然后切换了轨道,因此在某种意义上,UI始终处于“落后”状态,我不知道为什么第二个API领先于第一个! :S Any help is greatly appreciated! :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 })
    })
  }

Updated Answer 更新的答案

As discussed below, the original answer below is probably still relevant. 如下所述,下面的原始答案可能仍然有用。 However the first problem is the way this.updateCurrentlyPlaying is invoked. 但是,第一个问题是this.updateCurrentlyPlaying的调用方式。 In writing .then(this.updateCurrentlyPlaying()) , you are immediately invoking this.updateCurrentlyPlaying , which is passing undefined back into the Promise chain. 在编写.then(this.updateCurrentlyPlaying()) ,您将立即调用this.updateCurrentlyPlaying ,这this.updateCurrentlyPlaying undefined值传递回Promise链中。

Instead, you want something like: 相反,您需要以下内容:

 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()) } 

Original Answer 原始答案

My guess is that your code is fine, but Spotify isn't behaving the way you would expect it to. 我的猜测是您的代码很好,但是Spotify却没有您期望的方式。 When you POST to me/player/next , the endpoint immediately responds code 204 indicating that it received your request. 当您发布到me/player/next ,端点立即响应代码204,表明它已收到您的请求。

Indeed, that is what the Spotify API docs say: 实际上,这就是Spotify API文档所说的:

A completed request will return a 204 NO CONTENT response code, and then issue the command to the player. 完成的请求将返回204 NO CONTENT响应代码,然后向播放器发出命令。

This means that your code sees the 204 and immediately goes on to call the Spotify API for the current track. 这意味着您的代码会看到204,并立即继续为当前曲目调用Spotify API。 This occurs before the passed command to the player noted above has been invoked by Spotify's player. 这是 Spotify的播放器调用了传递command to the player 之前发生的。

I'm not very familiar with the Spotify API and I see this is in Beta - maybe they will provide a more elegant solution in the near future. 我对Spotify API不太熟悉,而且我看到它是Beta版-也许他们会在不久的将来提供更优雅的解决方案。 Until then, your best bet might be to retry the second call (with a timeout limit) a few times until you confirm that the track has indeed changed. 在此之前,最好的选择是重试第二次呼叫(具有超时限制),直到您确认音轨确实已更改。

Here's a quick example how you might implement that: 这是一个简单的示例,说明如何实现:

  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(); } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM