Spotify API,无法链接两个 API 调用 (Authorization-GetSong)
Spotify API, cannot Chaining two API calls (Authorization-GetSong)
简单地说,我正在尝试实现从 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);
但是,它returns对getSong
功能没有任何作用。我不确定,但我相信承诺不要等待 onload
。
另外,我尝试同步发送第一个请求,它给出了一个错误;
Error: Synchronous XHR processing not implemented
我不熟悉JavaScript上的编码,我的思维方式有什么问题吗?
你的承诺的问题是你需要解决或拒绝退出承诺并将令牌数据传递给下一个承诺或函数。
一个简单的 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);
})
});
简单地说,我正在尝试实现从 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);
但是,它returns对getSong
功能没有任何作用。我不确定,但我相信承诺不要等待 onload
。
另外,我尝试同步发送第一个请求,它给出了一个错误;
Error: Synchronous XHR processing not implemented
我不熟悉JavaScript上的编码,我的思维方式有什么问题吗?
你的承诺的问题是你需要解决或拒绝退出承诺并将令牌数据传递给下一个承诺或函数。
一个简单的 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);
})
});