免责声明:我 在开发人员体验小组的 Spotify 工作 。 这是一篇关于我们的新SDK探索async-await的个人博客文章。
最近,我在Spotify的团队向第三方开发人员发布了Web Playback SDK。 现在可以在网站和Web应用程序内部集成Spotify内容的回放。 在此处阅读完整的公告。
- 2016年:算法获胜的一年
- Spotify的总体规划
- SpotifySerenade / 2016年5月的Canciones de Mayo
- 将Spotify Web Playback SDK与async-await一起使用
- 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}!));
}
这为我们方便地公开了一堆变量: id
, track_uri
, track_name
, duration_ms
, album_name
, album_uri
, album_images
和album_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平台构建的东西!
快乐黑客