我只是试图实现从API获取令牌,然后获取带有令牌的歌曲。由于将令牌存储在全局变量中,并且在异步执行getAuthorizationToken
之后,getSong
函数立即被调用。因此,对于获取歌曲和获取HTTP 401,将使用undefined值调用该API。
var XMLHttpRequest = require('xhr2');
function getAuthorizationToken() {
let request = new XMLHttpRequest();
request.open('POST', 'https://accounts.spotify.com/api/token/', true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.setRequestHeader('Authorization', "Basic " + Buffer.from(config.clientID + ":" + config.clientSecret).toString('base64'));
request.onload = function () {
let data = JSON.parse(this.response);
if (request.status === 200) {
console.log(data['access_token']);
authorizationToken = data['access_token'];
}
};
request.send("grant_type=client_credentials");
}
function getSong() {
let request = new XMLHttpRequest();
request.open('GET', 'https://api.spotify.com/v1/tracks/2TpxZ7JUBn3uw46aR7qd6V', true);
request.setRequestHeader('Authorization', "Bearer " + authorizationToken);
request.onload = function () {
let data = JSON.parse(this.response);
console.log(data)
};
request.send();
}
getAuthorizatonToken();
getSong(); //this is invoked before authorizatonToken's value assigned.
我试图使用Promise
这样的链接;
function getAuthorizationToken() {
return new Promise(() => {
let request = new XMLHttpRequest();
request.open('POST', 'https://accounts.spotify.com/api/token/', true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.setRequestHeader('Authorization', "Basic " + Buffer.from(config.clientID + ":" + config.clientSecret).toString('base64'));
request.onload = function () {
let data = JSON.parse(this.response);
if (request.status === 200) {
console.log(data['access_token']);
authorizationToken = data['access_token'];
}
};
request.send("grant_type=client_credentials");
});
}
function getSong() {
// same method
}
getAuthorizationToken().then(getSong);
但是,对于getSong
函数,它什么也不返回。我不确定,但我相信诺言不会等待onload
。
此外,我尝试同步发送第一个请求,但它给出了一个错误;
错误:未执行同步XHR处理
我不熟悉JavaScript编码,我的思维方式出了什么问题?
答案 0 :(得分:1)
诺言的问题是您需要解决或拒绝退出诺言并将令牌数据传递给下一个诺言或函数。
一个简单的promise函数如下所示:
var promise = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo');
}, 300);
});
这是最终代码:
var config = require('./config.json');
var XMLHttpRequest = require('xhr2');
function getAuthorizationToken() {
return new Promise(function (resolve, reject) {
let request = new XMLHttpRequest();
request.open('POST', 'https://accounts.spotify.com/api/token/');
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.setRequestHeader('Authorization', "Basic " + Buffer.from(config.clientID + ":" + config.clientSecret).toString('base64'));
request.onload = function () {
if (request.status === 200) {
let responseBody = JSON.parse(this.response);
resolve(responseBody["access_token"]);
}else{
reject(request.status);
}
};
request.onerror = function () {
reject(Error("Network Error"));
};
request.send("grant_type=client_credentials");
});
}
function getSong(authorizationToken) {
return new Promise(function(resolve,reject) {
let request = new XMLHttpRequest();
request.open('GET', 'https://api.spotify.com/v1/tracks/2TpxZ7JUBn3uw46aR7qd6V', true);
request.setRequestHeader('Authorization', "Bearer " + authorizationToken);
request.onload = function () {
if (request.status === 200) {
let responseBody = JSON.parse(this.response);
resolve(responseBody);
}else{
reject(request.status);
}
};
request.onerror = function () {
reject(Error("Network Error"));
};
request.send();
});
}
getAuthorizationToken().then(function (authorizationToken) {
getSong(authorizationToken).then(function (data) {
console.log(data);
})
});