К вашему сведению, albIds
НЕ является глобальным. Это переменная области действия модуля.
Затем вам нужно понять, что await
ТОЛЬКО делает что-то полезное, если вы ожидаете обещание, связанное с завершением асинхронной операции. Это НЕ относится к вашей функции getAlbums()
. Хотя оно объявлено async
и возвращает обещание, оно не связано вообще с завершением асинхронных операций.
Вместо этого обещание выполняется задолго до того, как вы поместили какие-либо данные в массив albIds
. Таким образом, вы думаете, что массив пуст (потому что когда вы пытаетесь его использовать, в него еще ничего не вставлено).
Вот мое предложение:
const rp = require('request-promise');
//prints out albums 1-5 id's
const id = '3TVXtAsR1Inumwj472S9r4';
async function getAlbums(i) {
const albIds = new Array(5);
const authOptions = {
url: 'https://accounts.spotify.com/api/token',
headers: {'Authorization': 'Basic ' + (new Buffer.from(client_id + ':' + client_secret).toString('base64'))},
form: {grant_type: 'client_credentials'},
json: true
};
const body = await rp.post(authOptions, function(error, response, body) {
const data = {
market: "US",
limit: "5"
};
const q = querystring.stringify(data);
const token = body.access_token;
const options = {
url: 'https://api.spotify.com/v1/artists/' + id + '/albums?' + q,
headers: { 'Authorization': 'Bearer ' + token },
json: true
};
let result = await rp.get(options);
for (let j = 0; j < 5; j++) {
albIds.push(result.items[j].id);
}
// let resolved value be the array
return albIds;
};
async function fetchUsers() {
for (let i = 0; i < 5; i++) {
const albiIds = await getAlbums(i);
console.log(albIds[i]);
}
}
fetchUsers();
Сводка изменений:
- Переключиться на библиотеку запросов-обещаний, которая использует обещания для автоматической передачи результатов и проверки статуса 2xx. Это гораздо более совместимо с функцией
async
, и мы можем использовать с ней await
. - Сделать
albIds
разрешенным значением getAlbums()
, а не общей переменной с большей областью действия (намного более невосприимчив к проблемам параллелизма и гарантирует, что вы не сможете использовать его до того, как он будет готов. - В
fetchUsers()
используйте albIds
, полученное из обещания, возвращенного getAlbums()
. - Измените все переменные на
let
или const
, в зависимости от ситуации (здесь вообще не нужно использовать var
). - Используйте
await
при вызовах запроса-обещания для упрощения кода и быть совместимым с обещанием, что getAlbums()
возвращается.
FYI, если это довольно новый код, я бы прекратил использовать библиотеки request
или request-promise
как они официально устарели для новых разработок. Хотя они будут поддерживаться, они не будут получать новые функции, добавленные к ним со временем. Вы можете прочитать, почему это происходит, но в основном они существовали так долго, и node.js изменилось так сильно за это время, что они стали чем-то вроде беспорядка, чтобы поддерживать и двигаться вперед. Но есть так много пользователей, что они не могут по-настоящему вносить критические изменения в API, что они должны были бы сделать, чтобы действительно продолжать его продвигать (например, сделать его полностью ориентированным на обещания). И, поскольку есть ряд хороших альтернатив, имеющих более современный дизайн, они решили перевернуть будущее на другие альтернативы. Я лично использую got()
для большинства своих применений, но есть множество других вариантов на выбор.
См. Должен ли я использовать модуль 'request' для нового проекта? для получения дополнительной информации.