填充异步函数后返回数组-Node.js

时间:2018-11-29 13:38:03

标签: javascript node.js asynchronous

我想从API访问一些数据并遇到问题。我的代码正在从API中获取一些数据,并将其与API的本地副本进行比较。如果本地副本与从API获取的副本不匹配,我希望它在数组中存储一些数据。获取和比较工作正常。当我尝试填充数组并想把它还给我时,问题就出现了。 request函数是异步的,因此最后的返回值是不确定的。我的函数checkForDiff应该在for循环完成后返回此数组,因为在foor循环之后,该数组应该充满我需要的信息。我是Nodejs的新手,所以我真的不知道如何解决它。我需要在返回数组之前先将其填充,但是异步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 :(得分:0)

要获取正确的数据,您需要使用promises。不用请求回调,而使用promise。

由于checkForDiff()是一个异步函数,因此您应该从该函数返回一个Promise,而不要尝试返回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...
    });