Javascript 与异步代码和承诺抗争

Javascript 与异步代码和承诺抗争,javascript,asynchronous,Javascript,Asynchronous,我正在使用spotify SDK创建一个web播放器。执行此操作时,每次单击播放机中的任何播放按钮时,我都要执行sdk函数:player.getCurrentState(),以获取当前播放曲目的新专辑艺术、曲目名称和艺人名称。收到结果后,我希望HTML结构中的当前元素相应地改变。但是,如果第一次按下,歌曲会正常播放,但会显示错误消息,但第二次按下时,元素会相应改变。之后,当我在不同的轨道之间切换时,更改总是滞后于单击。我认为这是由于异步代码造成的,但我无法理解javascript中的这种异步性

我正在使用spotify SDK创建一个web播放器。执行此操作时,每次单击播放机中的任何播放按钮时,我都要执行sdk函数:
player.getCurrentState()
,以获取当前播放曲目的新专辑艺术、曲目名称和艺人名称。收到结果后,我希望HTML结构中的当前元素相应地改变。但是,如果第一次按下,歌曲会正常播放,但会显示错误消息,但第二次按下时,元素会相应改变。之后,当我在不同的轨道之间切换时,更改总是滞后于单击。我认为这是由于异步代码造成的,但我无法理解javascript中的这种异步性

document.getElementById("playbtn").addEventListener("click", function () {
           const play = ({spotify_uri, playerInstance: {_options: {getOAuthToken, id}}}) => {
                getOAuthToken(access_token => {
                    fetch(`https://api.spotify.com/v1/me/player/play?device_id=${id}`, {
                        method: 'PUT',
                        body: JSON.stringify({uris: [spotify_uri]}),
                        headers: {
                            'Content-Type': 'application/json', 'Authorization': `Bearer ${access_token}`
                        },
                    });
                });
            };
            play({
                playerInstance: player,
                spotify_uri: 'spotify:track:14iN3o8ptQ8cFVZTEmyQRV',
            });
            update();
}, false);


function update(){
        player.getCurrentState().then(state => {
            if (!state) {
                console.error('User is not playing music through the Web Playback SDK');
                return;
            }
            document.getElementById("album").src = state.track_window.current_track.album['images'][2]["url"];
            document.getElementById("trackname").innerHTML = state.track_window.current_track['name'];
            document.getElementById("artistname").innerHTML = state.track_window.current_track['artists'][0]['name'];
        });
}
我还尝试了async和await函数,但结果相同。谢谢你的帮助

Spotify文档:


我还认为,在我之前提出的一个问题中也出现了类似的异步问题:

你的一次点击后的问题是因为新歌没有加载,播放器也没有更新。在下面的演示中,我添加了
player.addListener('player\u state\u changed',update)在主函数中,因此事件将触发更新方法

var-player=null;
函数更新(changedStateEvent){
console.log(changedStateEvent);
player.getCurrentState()。然后(state=>{
如果(!状态){
console.error('用户未通过Web播放SDK播放音乐');
返回;
}
document.getElementById(“album”).src=state.track\u window.current\u track.album['images'][2][“url”];
document.getElementById(“trackname”).innerHTML=state.track_window.current_track['name'];
document.getElementById(“artistname”).innerHTML=state.track_window.current_track['Artisters'][0]['name'];
});
}
常量播放=({
spotify_uri,
玩家立场:{
_选项:{
getOAuthToken,
身份证件
}
}
}) => {
getOAuthToken(访问令牌=>{
取回(`https://api.spotify.com/v1/me/player/play?device_id=${id}`{
方法:'放',
正文:JSON.stringify({
uri:[spotify_uri]
}),
标题:{
“内容类型”:“应用程序/json”,
'Authorization':'Bearer${access_token}`
},
});
});
};
window.onPotifyWebPlayBacksdkReady=()=>{
//现在可以初始化Spotify.Player并使用SDK
player=newspotify.player({
姓名:“卡莉·雷·杰普森球员”,
getOAuthToken:回调=>{
//运行代码以获取新的访问令牌
回调(“此处的访问令牌”);
},
数量:0.5
});
//使用事件
// https://developer.spotify.com/documentation/web-playback-sdk/reference/#event-玩家状态已更改
addListener('player\u state\u changed',update');
}
document.getElementById(“playbtn”).addEventListener(“单击”,函数(){
玩({
玩家立场:玩家,
spotify_uri:'spotify:track:14iN3o8ptQ8cFVZTEmyQRV',
});

},假)向我们展示文章中编辑的
播放
功能。这基本上就是spotify SDK提供的play函数。虽然在我看来,您在获取请求完成之前启动更新有问题,但并未深入研究,因此您可能需要将更新函数包装到
。然后()
,并以获取的分辨率运行。基本上应该类似于
fetch(*你的东西*)。然后(()=>player.getCurrentState())。然后(*元素和控制台的东西*)
如果我正确理解了你的想法,我尝试将.then(function(){update();})添加到play()中函数。这给出了:TypeError:无法读取undefined的属性'then'。我还尝试在加载页面时在函数外部定义'const'play。非常感谢!这帮了我的忙。我最终将update()的所有内容放在player.addListener('player\u state\u changed',state=>{“HERE”})中,这很有效。