将Spotify Web Playback SDK与async-await一起使用

免责声明:我 在开发人员体验小组的 Spotify 工作 这是一篇关于我们的新SDK探索async-await的个人博客文章。

最近,我在Spotify的团队向第三方开发人员发布了Web Playback SDK。 现在可以在网站和Web应用程序内部集成Spotify内容的回放。 在此处阅读完整的公告。

随着JavaScript ES6中异步等待语法的引入,我决定写这篇文章来展示Web Playback SDK中这种新语法的强大功能。

对于那些在JavaScript中使用Promises的人来说,这很容易解释。 如果您没有使用Promises或JavaScript,那么遵循本文可能会更具挑战性。 您可能想先在Glitch上玩我们的Web Playback SDK演示。

简单的解释,下面是一些伪JavaScript,它们可以执行搜索并在Spotify上播放第一首歌:

 函数searchAndPlaySong(search_query){ 
返回searchOnSpotify(search_query).then(结果=> {
如果(结果长度> 0){
返回playSong(results [0] .spotify_uri);
}
});
}

让我们在上面撒一些异步等待盐:

 异步函数searchAndPlayFirstSong(search_query){ 
让结果=等待searchOnSpotify(search_query);
如果(results.length === 0)返回;
返回playSong(results [0] .spotify_uri);
}

而已! 它们都执行完全相同的动作。 这里没有什么新鲜事发生,它不是新功能,仅是Promises的语法糖。 无需将代码包装在嵌套的Promises中,我们可以像上面那样编写代码,以使其更易于阅读。

当我们编写异步时,它返回一个Promise。 当我们写等待时,我们期望一个承诺。 在成功返回Promise之前,它将不会运行下一行代码。 对于错误处理,您可以简单地使用JavaScript的老式try {} catch (err) {}

尽管您不需要,但我强烈建议您阅读Web回放SDK的快速入门指南,以更好地了解如何在自己的Web应用程序中设置SDK。

对于以前从未使用过SDK的人来说,这是您入门所需的最基本的HTML代码:

   



window.onSpotifyWebPlaybackSDKReady =()=> {
console.log(“ Web Playback SDK已准备就绪。我们有权访问Spotify.Player”);
console.log(window.Spotify.Player);
};



页面加载后,Spotify会自动加载一个外部其中包含我们要向外部开发人员隐藏的脚本。 加载后,我们将提供一个window.Spotify对象,并立即触发一个window.onSpotifyWebPlaybackSDKReady回调,以通知开发人员。

因此,考虑到这一点,它如何与async-await一起使用?

我们要做的第一件事是创建一个名为waitForSpotifyWebPlaybackSDKToLoad的异步方法,该方法应检查waitForSpotifyWebPlaybackSDKToLoad对象是否已定义,或者检查直到触发window.onSpotifyWebPlaybackSDKReady为止:

 异步函数waitForSpotifyWebPlaybackSDKToLoad(){ 
返回新的Promise(resolve => {
如果(window.Spotify){
resolve(window.Spotify);
}其他{
window.onSpotifyWebPlaybackSDKReady =()=> {
resolve(window.Spotify);
};
}
});
};

然后我们可以如下使用它:

  (异步()=> { 
const {Player} =等待waitForSpotifyWebPlaybackSDKToLoad();
console.log(“ Web Playback SDK已加载。”);
})();

看起来更干净,里面有一些很棒的抽象。

此时,SDK应该会加载到您的浏览器中,并且您应该能够访问我们异步方法中的Player变量。 我们需要传递我们的播放器名称,初始音量和访问令牌。

  const sdk = new Player({ 
名称:“ Web Playback SDK”,
音量:1.0,
getOAuthToken:回调=> {回调(“访问令牌”); }
});

您可能会问:我们为什么不在这里使用async-await? 因为这既不是异步的,也不使用Promises。 当实例化Player时,我们的配置存储在内存中,当我们稍后调用connect()方法时,它将继续执行请求,并在Spotify中创建播放器。

如上所述,我们需要将本地播放器连接到Spotify。 如SDK参考中提供的示例所示,这是一种异步方法:

  sdk.connect()。then(connected => { 
如果(已连接){
//连接成功
}
});

我们的异步等待朋友可以在这里提供一些帮助:

 让连接=等待sdk.connect(); 
如果(已连接){
//连接成功
}

播放器使用connect()连接到Spotify之后,它将在任何官方Spotify客户端或通过Web出现在“ Web播放SDK”(如我们先前在new Player(...)定义)下的用户“设备列表”。 GET /v1/me/player/devices下的API。

除非用户选择了您的设备,否则它将返回null 。 否则,SDK可以收集当前的本地播放状态。 让我们这样做并应用一些解构:

 让状态=等待sdk.getCurrentState(); 
如果(状态==空){
//尚未在此设备上播放
}其他{
让{
ID,
uri:track_uri,
名称:track_name,
duration_ms,
艺术家,
相册:{
名称:album_name,
uri:album_uri,
图片:album_images
}
} = state.track_window.current_track;
console.log(`您正在听$ {artists [0] .name}的$ {track_name}!));
}

这为我们方便地公开了一堆变量: idtrack_uritrack_nameduration_msalbum_namealbum_urialbum_imagesalbum_images 。 可爱!

提示:可以使用PUT /v1/me/player端点通过Web API自动将用户的回放传输到播放PUT /v1/me/player 。 为了简单起见,我们不会进行介绍。

但是,如果我们要等到用户选择了我们的设备,该怎么办? 我们可以定义一个名为waitUntilUserHasSelectedPlayer的方法,该方法检查getCurrentState()直到不返回null为止:

 异步函数waitUntilUserHasSelectedPlayer(sdk){ 
返回新的Promise(resolve => {
let interval = setInterval(async()=> {
让状态=等待sdk.getCurrentState();
如果(状态!==空){
解析(状态);
clearInterval(interval);
}
});
});
};

然后我们可以这样称呼它:

 让状态=等待waitUntilUserHasSelectedPlayer(sdk); 

connect()getCurrentState()相似,SDK参考中的任何方法(例如暂停,恢复,跳过等)都可以使用async-await,因为它们都返回Promises。 以下是一些代码示例向您展示:

获取音量:

 让音量=等待sdk.getVolume(); 
console.log(`获得音量:$ {volume * 100}%`);

设定音量:

 等待sdk.setVolume(0.5); 
console.log(“更新到50%!”);

暂停:

 等待sdk.pause(); 
console.log(“已暂停!”);

恢复:

 等待sdk.resume(); 
console.log(“恢复!”);

跳过曲目:

 等待sdk.nextTrack(); 
console.log(“跳过的曲目!”);

所有这些方法都可以在SDK参考中找到。

我们已经处理了加载,实例化,连接,等待用户选择播放器以及从播放器中读取和控制播放器的工作。 那事件呢?

事件是可能与您正在执行的操作异步的操作。 以下是一些示例:

  • 用户不再具有Spotify Premium帐户
  • 互联网连接丢失
  • 错误处理
  • 播放状态已更改

这些操作是异步的,但它们不使用Promises。 它们是事件监听器。 因此,它们不支持async-await,但是我们可以正常使用它们:

  sdk.on(“ player_state_changed”,状态=> { 
console.log(“播放状态已更改”,状态);
});

SDK参考中提供了所有受支持的事件。

我们通过异步等待经历了很多事情。 让我们回顾一下:

  • 通过检查window.Spotify由SDK定义进行加载
  • 使用new Player(...) 实例化我们的本地播放new Player(...)
  • 使用connect() 连接到我们的播放器
  • 等待用户选择我们的设备
  • 使用SDK中的现有代码进行事件处理
  • 检查本地播放状态

代码是什么样的? 这可能会有所帮助:

  window.onSpotifyWebPlaybackSDKReady =()=> {};异步函数waitForSpotifyWebPlaybackSDKToLoad(){ 
返回新的Promise(resolve => {
如果(window.Spotify){
resolve(window.Spotify);
}其他{
window.onSpotifyWebPlaybackSDKReady =()=> {
resolve(window.Spotify);
};
}
});
};
异步函数waitUntilUserHasSelectedPlayer(sdk){
返回新的Promise(resolve => {
let interval = setInterval(async()=> {
让状态=等待sdk.getCurrentState();
如果(状态!==空){
解析(状态);
clearInterval(interval);
}
});
});
};
(异步()=> {
const {Player} =等待waitForSpotifyWebPlaybackSDKToLoad();
const sdk = new Player({
名称:“ Web Playback SDK”,
音量:1.0,
getOAuthToken:回调=> {回调(“访问令牌”); }
});
sdk.on(“ player_state_changed”,状态=> {
//使用播放状态更改更新UI
});
让连接=等待sdk.connect();
如果(已连接){
让状态=等待waitUntilUserHasSelectedPlayer(sdk);
等待sdk.resume();
等待sdk.setVolume(0.5);
让{
ID,
uri:track_uri,
名称:track_name,
duration_ms,
艺术家,
相册:{
名称:album_name,
uri:album_uri,
图片:album_images
}
} = state.track_window.current_track;
console.log(`您正在听$ {artists [0] .name}的$ {track_name}!));
}
})();

这就是异步等待的力量! 该代码现在更易于遵循,类似于说明列表。 希望这将使与Spotify的深度集成更加无缝。

想要演示异步等待吗? 我们在毛刺上做成了一个。 一探究竟!

对async-await的支持是什么? 不错。 它在全球浏览器中支持约73%。 因为async-await只是语法糖,所以我们可以简单地使用流行的编译器(例如Babel.js)以优雅地具有100%浏览器覆盖率的方式来翻译我们的JavaScript。

我们正在努力打造最佳的开发者体验,我建议您查看Spotify for Developers体验。 如果您有任何反馈或建议,请随时与我们分享-我们很高兴收到您的来信!

最后,我await要看您用Spotify平台构建的东西!

快乐黑客