Возвращение массива после заполнения в асинхронной функции - Node.js - PullRequest
0 голосов
/ 29 ноября 2018

Я хочу получить доступ к некоторым данным из API и столкнулся с проблемой.Мой код извлекает некоторые данные из API, сравнивает их с локальной копией API.Я хочу, чтобы он сохранял некоторые данные в массиве, если локальная копия не совпадает с копией, полученной из API.Выборка и сравнение работает нормально.Проблема возникает, когда я пытаюсь заполнить массив и хочу вернуть его.Функция request является асинхронной, поэтому мое возвращаемое значение в конце будет неопределенным.Моя функция checkForDiff должна возвращать этот массив после того, как цикл for выполнен, потому что после цикла foor массив должен быть заполнен необходимой мне информацией.Я новичок в Nodejs, поэтому я действительно не знаю, как это исправить.Мне нужно заполнить массив перед его возвратом, но вызов async request вызывает у меня проблемы.Как я могу достичь такого поведения?Заранее спасибо за помощь

function checkForDiff(){
 let outdatedLanguages = [];

 var options = {
   url: 'https://xxxxxxxxxxxxxxxxxxxxxxxxx',
   headers: {'Key': 'xxxxxxxxxxxxxxxxxxxxxx'}
 };
 for(let index = 0; index < locales.length; index++){
    //Change url for new https request
    options.url = `https://xxxxxxx?locale=${locales[index].symbol}`
    //Send new https request to API
    request(options, (error, response, body)=>{
       var localState = hash(JSON.parse(filesystem.readFileSync(`./cards/cards-${locales[index].symbol}.json`)));
       var recentState = hash(JSON.parse(body));
       /If the local card base is not up to date, add locale to array
       if(localState !== recentState){
        outdatedLanguages.push(locales[index].symbol);
       }
    );
  }
 //Return outdatedLanguages array
 return outdatedLanguages;
}

1 Ответ

0 голосов
/ 29 ноября 2018

Чтобы получить правильные данные, вам нужно использовать обещания.Вместо обратного вызова запроса используйте обещание.

Поскольку checkForDiff() является асинхронной функцией, вы должны вернуть обещание из функции, а не пытаться вернуть outdatedLanguages.В вашем случае вам нужно использовать функцию Promise.all(), потому что у вас есть несколько асинхронных функций.В некотором смысле, Promise.all() ожидает выполнения всех задач.В другой части кода, где вы используете эту функцию, вы должны знать, что эта функция является обещанием, поэтому вы должны использовать ее соответствующим образом.По сути, вы можете сделать что-то вроде этого.

function checkForDiff() {

    let outdatedLanguages = [];
    let promises = [];

    var options = {
        url: 'https://xxxxxxxxxxxxxxxxxxxxxxxxx',
        headers: { 'Key': 'xxxxxxxxxxxxxxxxxxxxxx' }
    };
    for (let index = 0; index < locales.length; index++) {
        //Change url for new https request
        options.url = `https://xxxxxxx?locale=${locales[index].symbol}`

        promises.push(/* request as promise */);
    }

    return Promise.all(promises).then(() => outdatedLanguages);

}

Вы вызываете функцию следующим образом.

checkForDiff().then((outdatedLanguages) => {
    // outdatedLanguages is the array you want
})

Для запроса обещания вы можете использовать пакет request-promise.Используйте команду npm install --save request-promise.Затем включите пакет var rp = require('request-promise');.Пример запроса следующий:

var options = {
    uri: 'https://api.github.com/user/repos',
    qs: {
        access_token: 'xxxxx xxxxx' // -> uri + '?access_token=xxxxx%20xxxxx'
    },
    headers: {
        'User-Agent': 'Request-Promise'
    },
    json: true // Automatically parses the JSON string in the response
};

rp(options)
    .then(function (repos) {
        console.log('User has %d repos', repos.length);
    })
    .catch(function (err) {
        // API call failed...
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...