API Spotify, не может связать два вызова API (Authorization-GetSong) - PullRequest
0 голосов
/ 01 мая 2019

Просто я пытаюсь реализовать получение токена из API и после этого получить песню с токеном.Из-за хранения токена в глобальной переменной и после асинхронного выполнения getAuthorizationToken функция getSong вызывается немедленно.Поэтому API вызывается со значением undefined для получаемой песни и получения HTTP 401.

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, что не так с моим мышлением?

1 Ответ

1 голос
/ 01 мая 2019

Проблема с вашим обещанием заключается в том, что вам необходимо разрешить или отклонить выход из обещания и передать данные токена следующему обещанию или функции.

Простая функция обещания выглядит следующим образом:

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);        
    })
});
...