javascript - .then 在 promise 解决之前触发 - $.getJSON
问题描述
我目前正在使用 Spotify API 和 nodejs 包装器构建一个 Web 应用程序......但是,当我使用 $.getJSON() 时,.then 在承诺解决之前触发。例如,在我跳到下一首歌曲后,我试图更改网页上显示的专辑插图。但是,艺术品首先在歌曲之前发生变化,因此艺术品始终是上一首歌的……我的代码在下面。
index.js 中的路由:
router.get('/skipToNext', function skipToNext(req, res, next) {
spotifyApi.skipToNext()
.then(function(data) {
res.json(data.body);
}, function(err) {
console.log("Something went wrong! ", err);
});
});
我跳过歌曲的功能:
function skipToNext() {
$.getJSON('/skipToNext')
.then(function() {
changeAlbumArt();
}, function(err) {
console.log("error! ", err);
});
};
changAlbumArt:
function changeAlbumArt() {
$.getJSON('/currentPlayback')
.then( function(data) {
console.log("Change album art: " + data);
var albumCover = data.item.album.images[0];
var albumName = data.item.album.name;
var albumCoverUrl = albumCover["url"];
console.log("url: " + albumCoverUrl);
console.log("album name: " + albumName);
console.log("now playing: " + data);
$(".container-album-cover").css("background", "url(" + albumCoverUrl + ")");
});
};
谢谢大家的回答!
解决方案
查看路由代码,注意执行顺序:
- Route handler 函数进入,spotify api 调用开始。
- 这将返回一个承诺(我假设),在其中附加一个延续函数,并
res
在闭包中捕获。 - 此时,路由处理函数和平返回,因为该函数已完成对请求的处理。
- 一段时间后,api 调用返回(假设成功)并且 promise 解决了。
res.json(data.body)
被调用,但周围没有更多的上下文,因此这永远不会到达客户端。
您的问题是,没有什么能阻止路由处理程序函数过早返回。我可能是错的,但是除了使 ajax 调用同步之外,没有像样的方法来克服这个问题,这不是一个好的做法(而且可能根本不可能使用 spotify api)。好吧,至少在引入async/await
构造的 ES2017 之前不会。从节点 7.6 开始,您可以通过以下方式重写您的服务器代码:
router.get('/skipToNext', async (req, res, next) => {
try {
let data = await spotifyApi.skipToNext();
res.json(data.body);
} catch (err) {
console.log("Something went wrong! ", err);
};
});
这样,您的路由处理程序函数将暂停,直到 api 调用返回。然后恢复该功能。如果 Promise 解决了,您将在data
从 Promise 中解包的变量中获取返回的数据 - 如果它失败并被拒绝,将抛出异常。现在您可以输入res
变量并让路由处理函数返回。
推荐阅读
- javascript - 如何在按钮单击时缩放 html?
- excel - 创建循环以将 Excel 上传到 SQL 数据库
- php - Dockerfile 中的 Alpine 包冲突
- react-native - 如何使用 Reactnative 在地图上显示标记的描述
- php - 在具有不同域托管的 VPS 上安装 composer
- regex - 如何在开头或结尾匹配没有空格且没有附加字母的特定单词?
- c++ - 在类的构造函数中初始化一个二维向量
- angular - Angular Service Worker 间歇性地为旧版本的应用程序提供服务
- c# - 解析正则表达式查询
- node.js - NodeJS 应用程序如何以 sudo 身份重新启动?